use serde_json::Value;
use crate::chunk::Chunk;
pub fn extract_jsonl(text: &str) -> Vec<Chunk> {
let mut chunks = Vec::new();
let mut ordinal = 0usize;
let mut cursor = 0usize;
for line in text.split_inclusive('\n') {
let byte_start = cursor;
let byte_end = cursor + line.len();
cursor = byte_end;
let trimmed = line.trim();
if trimmed.is_empty() {
continue;
}
if let Some(chunk) = extract_line(trimmed, ordinal, byte_start, byte_end) {
chunks.push(chunk);
ordinal += 1;
}
}
chunks
}
fn extract_line(line: &str, ordinal: usize, byte_start: usize, byte_end: usize) -> Option<Chunk> {
let value: Value = serde_json::from_str(line).ok()?;
let outer = value.as_object()?;
let inner = outer.get("message").and_then(Value::as_object);
let content = lookup_content(outer, inner)?;
if content.trim().is_empty() {
return None;
}
let scopes: &[&serde_json::Map<String, Value>] = match inner {
Some(m) => &[outer, m],
None => std::slice::from_ref(&outer),
};
let role = lookup_string(scopes, &["role"]);
let session_id = lookup_string(
scopes,
&[
"session_id",
"sessionId",
"conversation_id",
"conversationId",
"thread_id",
"threadId",
],
);
let turn_id = lookup_string(
scopes,
&["turn_id", "turnId", "turn", "message_id", "messageId"],
);
let parent_turn_id = lookup_string(
scopes,
&[
"parent_turn_id",
"parentTurnId",
"parent_message_id",
"parentMessageId",
"parent_id",
"parentId",
"reply_to",
"replyTo",
],
);
let role_str = role.as_deref();
let name_is_participant = matches!(
role_str,
Some("user") | Some("system") | Some("assistant") | Some("developer")
);
let tool_name_aliases: &[&str] = if name_is_participant {
&["tool_name", "toolName", "tool"]
} else {
&["tool_name", "toolName", "tool", "name"]
};
let user_aliases: &[&str] = if name_is_participant {
&["user", "user_id", "userId", "author", "participant", "name"]
} else {
&["user", "user_id", "userId", "author", "participant"]
};
let tool_name = lookup_string(scopes, tool_name_aliases)
.or_else(|| content_block_tool_name(outer, inner))
.or_else(|| tool_calls_array_tool_name(outer, inner))
.or_else(|| legacy_function_call_tool_name(outer, inner));
let tool_call_id = lookup_string(
scopes,
&[
"tool_call_id",
"toolCallId",
"tool_use_id",
"toolUseId",
"call_id",
"callId",
],
)
.or_else(|| content_block_tool_call_id(outer, inner))
.or_else(|| tool_calls_array_tool_call_id(outer, inner))
.or_else(|| web_search_call_tool_call_id(outer, inner))
.or_else(|| file_search_call_tool_call_id(outer, inner))
.or_else(|| code_interpreter_call_tool_call_id(outer, inner))
.or_else(|| image_generation_call_tool_call_id(outer, inner))
.or_else(|| mcp_call_tool_call_id(outer, inner))
.or_else(|| mcp_approval_request_tool_call_id(outer, inner))
.or_else(|| mcp_approval_response_tool_call_id(outer, inner));
let timestamp_unix = lookup_timestamp(scopes, &["timestamp", "created_at", "createdAt", "ts"]);
let project = lookup_string(
scopes,
&["project", "project_id", "projectId", "repo", "repository"],
);
let user = lookup_string(scopes, user_aliases);
let topic = lookup_string(
scopes,
&["topic", "topic_id", "topicId", "subject", "category"],
);
let thread = lookup_string(scopes, &["thread", "thread_id", "threadId"]);
let participant_name = if name_is_participant {
lookup_string(scopes, &["name"])
} else {
None
};
let content_has_typed_tool_prefix = content.starts_with("[mcp_call:")
|| content.starts_with("[function_call:")
|| content.starts_with("[custom_tool_call:")
|| content.starts_with("[mcp_approval_request:");
let text = match (
role.as_deref(),
tool_name.as_deref(),
content_has_typed_tool_prefix,
) {
(Some("tool"), Some(name), false) => format!("[tool:{name}] {content}"),
(Some("function"), Some(name), false) => format!("[function:{name}] {content}"),
(Some(role), _, _) => match participant_name.as_deref() {
Some(pn) => format!("[{role}:{pn}] {content}"),
None => format!("[{role}] {content}"),
},
(None, Some(name), false) => format!("[tool:{name}] {content}"),
(None, _, true) | (None, None, false) => content,
};
Some(Chunk {
ordinal,
byte_start,
byte_end,
text,
role,
session_id,
turn_id,
parent_turn_id,
tool_name,
tool_call_id,
timestamp_unix,
project,
user,
topic,
thread,
})
}
fn scalar_text(obj: &serde_json::Map<String, Value>, key: &str) -> Option<String> {
obj.get(key)
.and_then(value_to_string)
.filter(|s| !s.trim().is_empty())
}
fn lookup_string(scopes: &[&serde_json::Map<String, Value>], keys: &[&str]) -> Option<String> {
scopes
.iter()
.copied()
.find_map(|obj| keys.iter().find_map(|key| scalar_text(obj, key)))
}
fn lookup_timestamp(scopes: &[&serde_json::Map<String, Value>], keys: &[&str]) -> Option<i64> {
scopes.iter().copied().find_map(|obj| {
keys.iter().find_map(|key| {
let value = obj.get(*key)?;
match value {
Value::Number(n) => n.as_i64().or_else(|| n.as_u64().map(|u| u as i64)),
Value::String(s) => s.trim().parse::<i64>().ok(),
_ => None,
}
})
})
}
fn lookup_content(
outer: &serde_json::Map<String, Value>,
inner: Option<&serde_json::Map<String, Value>>,
) -> Option<String> {
fn from(obj: &serde_json::Map<String, Value>) -> Option<String> {
obj.get("content")
.and_then(content_to_text)
.or_else(|| output_text_with_annotations_to_text(obj))
.or_else(|| scalar_text(obj, "text"))
.or_else(|| {
obj.get("parts")
.filter(|v| v.is_array())
.and_then(content_to_text)
})
}
if let Some(text) = from(outer) {
return Some(append_chat_completions_annotations(text, outer));
}
if let Some(scope) = inner {
if let Some(text) = from(scope) {
return Some(append_chat_completions_annotations(text, scope));
}
}
let direct = scalar_text(outer, "message").or_else(|| scalar_text(outer, "body"));
if direct.is_some() {
return direct;
}
let is_mcp_call = |obj: &serde_json::Map<String, Value>| {
obj.get("type").and_then(Value::as_str) == Some("mcp_call")
};
if is_mcp_call(outer) || inner.is_some_and(is_mcp_call) {
return mcp_call_line_to_text(outer).or_else(|| inner.and_then(mcp_call_line_to_text));
}
let is_mcp_approval_request = |obj: &serde_json::Map<String, Value>| {
obj.get("type").and_then(Value::as_str) == Some("mcp_approval_request")
};
if is_mcp_approval_request(outer) || inner.is_some_and(is_mcp_approval_request) {
return mcp_approval_request_line_to_text(outer)
.or_else(|| inner.and_then(mcp_approval_request_line_to_text));
}
let is_function_call = |obj: &serde_json::Map<String, Value>| {
obj.get("type").and_then(Value::as_str) == Some("function_call")
};
if is_function_call(outer) || inner.is_some_and(is_function_call) {
return function_call_line_to_text(outer)
.or_else(|| inner.and_then(function_call_line_to_text));
}
let is_custom_tool_call = |obj: &serde_json::Map<String, Value>| {
obj.get("type").and_then(Value::as_str) == Some("custom_tool_call")
};
if is_custom_tool_call(outer) || inner.is_some_and(is_custom_tool_call) {
return custom_tool_call_line_to_text(outer)
.or_else(|| inner.and_then(custom_tool_call_line_to_text));
}
payload_text(outer, "arguments")
.or_else(|| payload_text(outer, "input"))
.or_else(|| inner.and_then(|m| payload_text(m, "arguments")))
.or_else(|| inner.and_then(|m| payload_text(m, "input")))
.or_else(|| tool_calls_array_text(outer))
.or_else(|| inner.and_then(tool_calls_array_text))
.or_else(|| legacy_function_call_text(outer))
.or_else(|| inner.and_then(legacy_function_call_text))
.or_else(|| legacy_assistant_audio_text(outer))
.or_else(|| inner.and_then(legacy_assistant_audio_text))
.or_else(|| legacy_assistant_refusal_text(outer))
.or_else(|| inner.and_then(legacy_assistant_refusal_text))
.or_else(|| legacy_assistant_reasoning_content_text(outer))
.or_else(|| inner.and_then(legacy_assistant_reasoning_content_text))
.or_else(|| web_search_call_line_to_text(outer))
.or_else(|| inner.and_then(web_search_call_line_to_text))
.or_else(|| file_search_call_line_to_text(outer))
.or_else(|| inner.and_then(file_search_call_line_to_text))
.or_else(|| code_interpreter_call_line_to_text(outer))
.or_else(|| inner.and_then(code_interpreter_call_line_to_text))
.or_else(|| local_shell_call_line_to_text(outer))
.or_else(|| inner.and_then(local_shell_call_line_to_text))
.or_else(|| local_shell_call_output_line_to_text(outer))
.or_else(|| inner.and_then(local_shell_call_output_line_to_text))
.or_else(|| function_call_output_line_to_text(outer))
.or_else(|| inner.and_then(function_call_output_line_to_text))
.or_else(|| code_interpreter_call_output_line_to_text(outer))
.or_else(|| inner.and_then(code_interpreter_call_output_line_to_text))
.or_else(|| custom_tool_call_output_line_to_text(outer))
.or_else(|| inner.and_then(custom_tool_call_output_line_to_text))
.or_else(|| computer_call_line_to_text(outer))
.or_else(|| inner.and_then(computer_call_line_to_text))
.or_else(|| computer_call_output_line_to_text(outer))
.or_else(|| inner.and_then(computer_call_output_line_to_text))
.or_else(|| reasoning_line_to_text(outer))
.or_else(|| inner.and_then(reasoning_line_to_text))
.or_else(|| image_generation_call_line_to_text(outer))
.or_else(|| inner.and_then(image_generation_call_line_to_text))
.or_else(|| mcp_list_tools_line_to_text(outer))
.or_else(|| inner.and_then(mcp_list_tools_line_to_text))
.or_else(|| mcp_approval_response_line_to_text(outer))
.or_else(|| inner.and_then(mcp_approval_response_line_to_text))
}
fn payload_text(obj: &serde_json::Map<String, Value>, key: &str) -> Option<String> {
let value = obj.get(key)?;
match value {
Value::String(s) if !s.trim().is_empty() => Some(s.clone()),
Value::Number(_) | Value::Bool(_) => Some(value.to_string()),
Value::Object(map) if !map.is_empty() => serde_json::to_string(value).ok(),
Value::Array(arr) if !arr.is_empty() => serde_json::to_string(value).ok(),
_ => None,
}
}
fn value_to_string(value: &Value) -> Option<String> {
match value {
Value::String(s) if !s.trim().is_empty() => Some(s.clone()),
Value::Number(_) | Value::Bool(_) => Some(value.to_string()),
_ => None,
}
}
fn content_to_text(v: &Value) -> Option<String> {
match v {
Value::String(s) if !s.trim().is_empty() => Some(s.clone()),
Value::Array(arr) => {
let parts: Vec<String> = arr
.iter()
.filter_map(|item| match item {
Value::String(s) if !s.trim().is_empty() => Some(s.clone()),
Value::Object(obj) => reasoning_text_block_to_text(obj)
.or_else(|| refusal_block_to_text(obj))
.or_else(|| output_text_with_annotations_to_text(obj))
.or_else(|| anthropic_text_with_citations_to_text(obj))
.or_else(|| {
obj.get("text")
.and_then(Value::as_str)
.map(str::to_string)
.filter(|s| !s.trim().is_empty())
})
.or_else(|| tool_result_error_block_to_text(obj))
.or_else(|| mcp_tool_result_block_to_text(obj))
.or_else(|| web_search_tool_result_block_to_text(obj))
.or_else(|| web_fetch_tool_result_block_to_text(obj))
.or_else(|| code_execution_tool_result_block_to_text(obj))
.or_else(|| bash_code_execution_tool_result_block_to_text(obj))
.or_else(|| search_result_block_to_text(obj))
.or_else(|| obj.get("content").and_then(content_to_text))
.or_else(|| tool_use_block_to_text(obj))
.or_else(|| server_tool_use_block_to_text(obj))
.or_else(|| mcp_tool_use_block_to_text(obj))
.or_else(|| function_call_block_to_text(obj))
.or_else(|| function_call_output_block_to_text(obj))
.or_else(|| gemini_function_call_part_to_text(obj))
.or_else(|| gemini_function_response_part_to_text(obj))
.or_else(|| thinking_block_to_text(obj))
.or_else(|| image_block_to_text(obj))
.or_else(|| input_image_block_to_text(obj))
.or_else(|| chat_completions_image_url_block_to_text(obj))
.or_else(|| input_file_block_to_text(obj))
.or_else(|| input_audio_block_to_text(obj))
.or_else(|| output_audio_block_to_text(obj))
.or_else(|| document_block_to_text(obj)),
_ => None,
})
.collect();
if parts.is_empty() {
None
} else {
Some(parts.join("\n"))
}
}
_ => None,
}
}
fn tool_use_block_to_text(obj: &serde_json::Map<String, Value>) -> Option<String> {
if obj.get("type").and_then(Value::as_str) != Some("tool_use") {
return None;
}
let name = obj
.get("name")
.and_then(Value::as_str)
.map(str::trim)
.filter(|s| !s.is_empty())?;
let input = obj.get("input").and_then(|v| match v {
Value::String(s) if !s.trim().is_empty() => Some(s.clone()),
Value::Number(_) | Value::Bool(_) => Some(v.to_string()),
Value::Object(map) if !map.is_empty() => serde_json::to_string(v).ok(),
Value::Array(arr) if !arr.is_empty() => serde_json::to_string(v).ok(),
_ => None,
});
Some(match input {
Some(input) => format!("[tool_use:{name}] {input}"),
None => format!("[tool_use:{name}]"),
})
}
fn server_tool_use_block_to_text(obj: &serde_json::Map<String, Value>) -> Option<String> {
if obj.get("type").and_then(Value::as_str) != Some("server_tool_use") {
return None;
}
let name = obj
.get("name")
.and_then(Value::as_str)
.map(str::trim)
.filter(|s| !s.is_empty())?;
let input = obj.get("input").and_then(|v| match v {
Value::String(s) if !s.trim().is_empty() => Some(s.clone()),
Value::Number(_) | Value::Bool(_) => Some(v.to_string()),
Value::Object(map) if !map.is_empty() => serde_json::to_string(v).ok(),
Value::Array(arr) if !arr.is_empty() => serde_json::to_string(v).ok(),
_ => None,
});
Some(match input {
Some(input) => format!("[server_tool_use:{name}] {input}"),
None => format!("[server_tool_use:{name}]"),
})
}
fn mcp_tool_use_block_to_text(obj: &serde_json::Map<String, Value>) -> Option<String> {
if obj.get("type").and_then(Value::as_str) != Some("mcp_tool_use") {
return None;
}
let name = obj
.get("name")
.and_then(Value::as_str)
.map(str::trim)
.filter(|s| !s.is_empty())?;
let server = obj
.get("server_name")
.and_then(Value::as_str)
.map(str::trim)
.filter(|s| !s.is_empty());
let label = match server {
Some(s) => format!("{s}/{name}"),
None => name.to_string(),
};
let input = obj.get("input").and_then(|v| match v {
Value::String(s) if !s.trim().is_empty() => Some(s.clone()),
Value::Number(_) | Value::Bool(_) => Some(v.to_string()),
Value::Object(map) if !map.is_empty() => serde_json::to_string(v).ok(),
Value::Array(arr) if !arr.is_empty() => serde_json::to_string(v).ok(),
_ => None,
});
Some(match input {
Some(input) => format!("[mcp_tool_use:{label}] {input}"),
None => format!("[mcp_tool_use:{label}]"),
})
}
fn function_call_block_to_text(obj: &serde_json::Map<String, Value>) -> Option<String> {
if obj.get("type").and_then(Value::as_str) != Some("function_call") {
return None;
}
let name = obj
.get("name")
.and_then(Value::as_str)
.map(str::trim)
.filter(|s| !s.is_empty())?;
let arguments = arguments_value_to_text(obj.get("arguments"));
Some(match arguments {
Some(args) => format!("[tool_use:{name}] {args}"),
None => format!("[tool_use:{name}]"),
})
}
fn function_call_output_block_to_text(obj: &serde_json::Map<String, Value>) -> Option<String> {
if obj.get("type").and_then(Value::as_str) != Some("function_call_output") {
return None;
}
let output = arguments_value_to_text(obj.get("output"))?;
Some(format!("[tool_result] {output}"))
}
fn gemini_function_call_part_to_text(obj: &serde_json::Map<String, Value>) -> Option<String> {
let inner = obj.get("functionCall")?.as_object()?;
let name = inner
.get("name")
.and_then(Value::as_str)
.map(str::trim)
.filter(|s| !s.is_empty())?;
let args = arguments_value_to_text(inner.get("args"));
Some(match args {
Some(args) => format!("[tool_use:{name}] {args}"),
None => format!("[tool_use:{name}]"),
})
}
fn gemini_function_response_part_to_text(obj: &serde_json::Map<String, Value>) -> Option<String> {
let inner = obj.get("functionResponse")?.as_object()?;
let response = arguments_value_to_text(inner.get("response"))?;
Some(format!("[tool_result] {response}"))
}
fn thinking_block_to_text(obj: &serde_json::Map<String, Value>) -> Option<String> {
if obj.get("type").and_then(Value::as_str) != Some("thinking") {
return None;
}
let text = scalar_text(obj, "thinking")?;
Some(format!("[thinking] {text}"))
}
fn reasoning_text_block_to_text(obj: &serde_json::Map<String, Value>) -> Option<String> {
if obj.get("type").and_then(Value::as_str) != Some("reasoning_text") {
return None;
}
let text = scalar_text(obj, "text")?;
Some(format!("[thinking] {text}"))
}
fn refusal_block_to_text(obj: &serde_json::Map<String, Value>) -> Option<String> {
if obj.get("type").and_then(Value::as_str) != Some("refusal") {
return None;
}
let text = scalar_text(obj, "refusal")?;
Some(format!("[refusal] {text}"))
}
fn output_text_with_annotations_to_text(obj: &serde_json::Map<String, Value>) -> Option<String> {
if obj.get("type").and_then(Value::as_str) != Some("output_text") {
return None;
}
let text = obj
.get("text")
.and_then(Value::as_str)
.map(str::trim)
.filter(|s| !s.is_empty())?;
let annotations = obj.get("annotations").and_then(Value::as_array)?;
let citation_lines: Vec<String> = annotations.iter().filter_map(annotation_to_text).collect();
if citation_lines.is_empty() {
return None;
}
let mut result = String::from(text);
for line in citation_lines {
result.push('\n');
result.push_str(&line);
}
Some(result)
}
fn annotation_to_text(v: &Value) -> Option<String> {
let obj = v.as_object()?;
let ty = obj.get("type").and_then(Value::as_str)?;
match ty {
"url_citation" => {
let url = scalar_text(obj, "url")?;
let title = scalar_text(obj, "title");
Some(match title {
Some(t) => format!("[url_citation] {url} {t}"),
None => format!("[url_citation] {url}"),
})
}
"file_citation" => {
let file_id = scalar_text(obj, "file_id");
let filename = scalar_text(obj, "filename");
match (file_id, filename) {
(Some(id), Some(name)) => Some(format!("[file_citation] {id} {name}")),
(Some(id), None) => Some(format!("[file_citation] {id}")),
(None, Some(name)) => Some(format!("[file_citation] {name}")),
(None, None) => None,
}
}
"container_file_citation" => {
let file_id = scalar_text(obj, "file_id");
let filename = scalar_text(obj, "filename");
match (file_id, filename) {
(Some(id), Some(name)) => Some(format!("[container_file_citation] {id} {name}")),
(Some(id), None) => Some(format!("[container_file_citation] {id}")),
(None, Some(name)) => Some(format!("[container_file_citation] {name}")),
(None, None) => None,
}
}
_ => None,
}
}
fn append_chat_completions_annotations(
text: String,
obj: &serde_json::Map<String, Value>,
) -> String {
let Some(annotations) = obj.get("annotations").and_then(Value::as_array) else {
return text;
};
let citation_lines: Vec<String> = annotations
.iter()
.filter_map(chat_completions_annotation_to_text)
.collect();
if citation_lines.is_empty() {
return text;
}
let mut result = text;
for line in citation_lines {
result.push('\n');
result.push_str(&line);
}
result
}
fn chat_completions_annotation_to_text(v: &Value) -> Option<String> {
let obj = v.as_object()?;
let ty = obj.get("type").and_then(Value::as_str)?;
match ty {
"url_citation" => {
let inner = obj.get("url_citation").and_then(Value::as_object)?;
let url = scalar_text(inner, "url")?;
let title = scalar_text(inner, "title");
Some(match title {
Some(t) => format!("[url_citation] {url} {t}"),
None => format!("[url_citation] {url}"),
})
}
_ => None,
}
}
fn anthropic_text_with_citations_to_text(obj: &serde_json::Map<String, Value>) -> Option<String> {
if obj.get("type").and_then(Value::as_str) != Some("text") {
return None;
}
let text = obj
.get("text")
.and_then(Value::as_str)
.map(str::trim)
.filter(|s| !s.is_empty())?;
let citations = obj.get("citations").and_then(Value::as_array)?;
let citation_lines: Vec<String> = citations
.iter()
.filter_map(anthropic_citation_to_text)
.collect();
if citation_lines.is_empty() {
return None;
}
let mut result = String::from(text);
for line in citation_lines {
result.push('\n');
result.push_str(&line);
}
Some(result)
}
fn anthropic_citation_to_text(v: &Value) -> Option<String> {
let obj = v.as_object()?;
let ty = obj.get("type").and_then(Value::as_str)?;
match ty {
"char_location" | "page_location" | "content_block_location" => {
let title = scalar_text(obj, "document_title");
let cited = scalar_text(obj, "cited_text");
let body = match (title, cited) {
(Some(t), Some(c)) => format!("{t} {c}"),
(Some(t), None) => t,
(None, Some(c)) => c,
(None, None) => return None,
};
Some(format!("[citation:{ty}] {body}"))
}
"web_search_result_location" => {
let body = join_non_blank_anchors(obj, &["url", "title", "cited_text"])?;
Some(format!("[citation:{ty}] {body}"))
}
"search_result_location" => {
let body = join_non_blank_anchors(obj, &["source", "title", "cited_text"])?;
Some(format!("[citation:{ty}] {body}"))
}
_ => None,
}
}
fn join_non_blank_anchors(obj: &serde_json::Map<String, Value>, keys: &[&str]) -> Option<String> {
let parts: Vec<String> = keys.iter().filter_map(|k| scalar_text(obj, k)).collect();
if parts.is_empty() {
None
} else {
Some(parts.join(" "))
}
}
fn image_block_to_text(obj: &serde_json::Map<String, Value>) -> Option<String> {
if obj.get("type").and_then(Value::as_str) != Some("image") {
return None;
}
let source = obj.get("source").and_then(Value::as_object)?;
if let Some(url) = scalar_text(source, "url") {
return Some(format!("[image] {url}"));
}
let media_type = scalar_text(source, "media_type")?;
Some(format!("[image:{media_type}]"))
}
fn input_image_block_to_text(obj: &serde_json::Map<String, Value>) -> Option<String> {
if obj.get("type").and_then(Value::as_str) != Some("input_image") {
return None;
}
if let Some(url) = scalar_text(obj, "image_url") {
if let Some(rest) = url.strip_prefix("data:") {
if let Some((media_type, _)) = rest.split_once(';') {
let media_type = media_type.trim();
if !media_type.is_empty() {
return Some(format!("[input_image:{media_type}]"));
}
}
} else {
return Some(format!("[input_image] {url}"));
}
}
let file_id = scalar_text(obj, "file_id")?;
Some(format!("[input_image:file] {file_id}"))
}
fn chat_completions_image_url_block_to_text(
obj: &serde_json::Map<String, Value>,
) -> Option<String> {
if obj.get("type").and_then(Value::as_str) != Some("image_url") {
return None;
}
let image_url = obj.get("image_url").and_then(Value::as_object)?;
let url = scalar_text(image_url, "url")?;
if let Some(rest) = url.strip_prefix("data:") {
if let Some((media_type, _)) = rest.split_once(';') {
let media_type = media_type.trim();
if !media_type.is_empty() {
return Some(format!("[image_url:{media_type}]"));
}
}
return None;
}
Some(format!("[image_url] {url}"))
}
fn input_file_block_to_text(obj: &serde_json::Map<String, Value>) -> Option<String> {
if obj.get("type").and_then(Value::as_str) != Some("input_file") {
return None;
}
if let Some(url) = scalar_text(obj, "file_url") {
if let Some(rest) = url.strip_prefix("data:") {
if let Some((media_type, _)) = rest.split_once(';') {
let media_type = media_type.trim();
if !media_type.is_empty() {
return Some(format!("[input_file:{media_type}]"));
}
}
} else {
return Some(format!("[input_file] {url}"));
}
}
if let Some(filename) = scalar_text(obj, "filename") {
return Some(format!("[input_file] {filename}"));
}
if let Some(data) = scalar_text(obj, "file_data")
&& let Some(rest) = data.strip_prefix("data:")
&& let Some((media_type, _)) = rest.split_once(';')
{
let media_type = media_type.trim();
if !media_type.is_empty() {
return Some(format!("[input_file:{media_type}]"));
}
}
let file_id = scalar_text(obj, "file_id")?;
Some(format!("[input_file:file] {file_id}"))
}
fn input_audio_block_to_text(obj: &serde_json::Map<String, Value>) -> Option<String> {
if obj.get("type").and_then(Value::as_str) != Some("input_audio") {
return None;
}
if let Some(transcript) = scalar_text(obj, "transcript") {
return Some(format!("[input_audio] {transcript}"));
}
if let Some(file_id) = scalar_text(obj, "file_id") {
return Some(format!("[input_audio:file] {file_id}"));
}
let nested = obj.get("input_audio").and_then(Value::as_object)?;
let format = scalar_text(nested, "format")?;
Some(format!("[input_audio:{format}]"))
}
fn output_audio_block_to_text(obj: &serde_json::Map<String, Value>) -> Option<String> {
if obj.get("type").and_then(Value::as_str) != Some("output_audio") {
return None;
}
if let Some(transcript) = scalar_text(obj, "transcript") {
return Some(format!("[output_audio] {transcript}"));
}
if let Some(file_id) = scalar_text(obj, "file_id") {
return Some(format!("[output_audio:file] {file_id}"));
}
if let Some(format) = scalar_text(obj, "format") {
return Some(format!("[output_audio:{format}]"));
}
let nested = obj.get("output_audio").and_then(Value::as_object)?;
let format = scalar_text(nested, "format")?;
Some(format!("[output_audio:{format}]"))
}
fn document_block_to_text(obj: &serde_json::Map<String, Value>) -> Option<String> {
if obj.get("type").and_then(Value::as_str) != Some("document") {
return None;
}
let source = obj.get("source").and_then(Value::as_object)?;
let source_type = scalar_text(source, "type");
if source_type.as_deref() == Some("text")
&& let Some(data) = scalar_text(source, "data")
{
return Some(format!("[document] {data}"));
}
if source_type.as_deref() == Some("content")
&& let Some(inner) = source.get("content").and_then(content_to_text)
{
return Some(format!("[document] {inner}"));
}
if let Some(url) = scalar_text(source, "url") {
return Some(format!("[document] {url}"));
}
let media_type = scalar_text(source, "media_type")?;
Some(format!("[document:{media_type}]"))
}
fn tool_result_error_block_to_text(obj: &serde_json::Map<String, Value>) -> Option<String> {
if obj.get("type").and_then(Value::as_str) != Some("tool_result") {
return None;
}
if obj.get("is_error").and_then(Value::as_bool) != Some(true) {
return None;
}
let inner = obj.get("content").and_then(content_to_text)?;
Some(format!("[tool_error] {inner}"))
}
fn mcp_tool_result_block_to_text(obj: &serde_json::Map<String, Value>) -> Option<String> {
if obj.get("type").and_then(Value::as_str) != Some("mcp_tool_result") {
return None;
}
let inner = obj.get("content").and_then(content_to_text)?;
let prefix = if obj.get("is_error").and_then(Value::as_bool) == Some(true) {
"[mcp_tool_error]"
} else {
"[mcp_tool_result]"
};
Some(format!("{prefix} {inner}"))
}
fn web_search_tool_result_block_to_text(obj: &serde_json::Map<String, Value>) -> Option<String> {
if obj.get("type").and_then(Value::as_str) != Some("web_search_tool_result") {
return None;
}
match obj.get("content")? {
Value::Array(arr) => {
let parts: Vec<String> = arr
.iter()
.filter_map(|item| {
let entry = item.as_object()?;
if entry.get("type").and_then(Value::as_str) != Some("web_search_result") {
return None;
}
let title = scalar_text(entry, "title");
let url = scalar_text(entry, "url");
let body = match (title, url) {
(Some(t), Some(u)) => format!("{t} {u}"),
(Some(t), None) => t,
(None, Some(u)) => u,
(None, None) => return None,
};
Some(format!("[web_search_tool_result] {body}"))
})
.collect();
if parts.is_empty() {
None
} else {
Some(parts.join("\n"))
}
}
Value::Object(err) => {
if err.get("type").and_then(Value::as_str) != Some("web_search_tool_result_error") {
return None;
}
let code = scalar_text(err, "error_code")?;
Some(format!("[web_search_tool_error] error_code={code}"))
}
_ => None,
}
}
fn web_fetch_tool_result_block_to_text(obj: &serde_json::Map<String, Value>) -> Option<String> {
if obj.get("type").and_then(Value::as_str) != Some("web_fetch_tool_result") {
return None;
}
let inner = obj.get("content")?.as_object()?;
match inner.get("type").and_then(Value::as_str)? {
"web_fetch_result" => {
let url = scalar_text(inner, "url")?;
let nested = inner
.get("content")
.and_then(Value::as_object)
.and_then(document_block_to_text);
Some(match nested {
Some(doc) => format!("[web_fetch_tool_result] {url}\n{doc}"),
None => format!("[web_fetch_tool_result] {url}"),
})
}
"web_fetch_tool_result_error" => {
let code = scalar_text(inner, "error_code")?;
Some(format!("[web_fetch_tool_error] error_code={code}"))
}
_ => None,
}
}
fn code_execution_tool_result_block_to_text(
obj: &serde_json::Map<String, Value>,
) -> Option<String> {
if obj.get("type").and_then(Value::as_str) != Some("code_execution_tool_result") {
return None;
}
let inner = obj.get("content")?.as_object()?;
match inner.get("type").and_then(Value::as_str)? {
"code_execution_result" => {
let mut filtered = serde_json::Map::new();
if let Some(rc) = inner.get("return_code")
&& matches!(rc, Value::Number(_))
{
filtered.insert("return_code".to_string(), rc.clone());
}
if let Some(s) = scalar_text(inner, "stdout") {
filtered.insert("stdout".to_string(), Value::String(s));
}
if let Some(s) = scalar_text(inner, "stderr") {
filtered.insert("stderr".to_string(), Value::String(s));
}
let output_lines: Vec<String> = inner
.get("content")
.and_then(Value::as_array)
.into_iter()
.flatten()
.filter_map(code_execution_output_entry_to_text)
.collect();
if filtered.is_empty() && output_lines.is_empty() {
return None;
}
let mut rendered = if filtered.is_empty() {
"[code_execution_result]".to_string()
} else {
let json = serde_json::to_string(&Value::Object(filtered)).ok()?;
format!("[code_execution_result] {json}")
};
for line in output_lines {
rendered.push('\n');
rendered.push_str(&line);
}
Some(rendered)
}
"code_execution_tool_result_error" => {
let code = scalar_text(inner, "error_code")?;
Some(format!("[code_execution_error] error_code={code}"))
}
_ => None,
}
}
fn code_execution_output_entry_to_text(entry: &Value) -> Option<String> {
let obj = entry.as_object()?;
if obj.get("type").and_then(Value::as_str) != Some("code_execution_output") {
return None;
}
let file_id = scalar_text(obj, "file_id")?;
Some(format!("[code_execution_output] {file_id}"))
}
fn bash_code_execution_tool_result_block_to_text(
obj: &serde_json::Map<String, Value>,
) -> Option<String> {
if obj.get("type").and_then(Value::as_str) != Some("bash_code_execution_tool_result") {
return None;
}
let inner = obj.get("content")?.as_object()?;
match inner.get("type").and_then(Value::as_str)? {
"bash_code_execution_result" => {
let mut filtered = serde_json::Map::new();
if let Some(rc) = inner.get("return_code")
&& matches!(rc, Value::Number(_))
{
filtered.insert("return_code".to_string(), rc.clone());
}
if let Some(s) = scalar_text(inner, "stdout") {
filtered.insert("stdout".to_string(), Value::String(s));
}
if let Some(s) = scalar_text(inner, "stderr") {
filtered.insert("stderr".to_string(), Value::String(s));
}
if filtered.is_empty() {
return None;
}
let json = serde_json::to_string(&Value::Object(filtered)).ok()?;
Some(format!("[bash_code_execution_result] {json}"))
}
"bash_code_execution_tool_result_error" => {
let code = scalar_text(inner, "error_code")?;
Some(format!("[bash_code_execution_error] error_code={code}"))
}
_ => None,
}
}
fn search_result_block_to_text(obj: &serde_json::Map<String, Value>) -> Option<String> {
if obj.get("type").and_then(Value::as_str) != Some("search_result") {
return None;
}
let source = scalar_text(obj, "source");
let title = scalar_text(obj, "title");
let inner = obj.get("content").and_then(content_to_text);
let header = match (source.as_deref(), title.as_deref()) {
(Some(s), Some(t)) => format!("[search_result] {s} {t}"),
(Some(s), None) => format!("[search_result] {s}"),
(None, Some(t)) => format!("[search_result] {t}"),
(None, None) => return None,
};
Some(match inner {
Some(text) => format!("{header}\n{text}"),
None => header,
})
}
fn web_search_call_line_to_text(obj: &serde_json::Map<String, Value>) -> Option<String> {
if obj.get("type").and_then(Value::as_str) != Some("web_search_call") {
return None;
}
let action = obj.get("action").and_then(Value::as_object)?;
let action_type = scalar_text(action, "type")?;
let mut filtered = serde_json::Map::new();
for key in ["pattern", "query", "url"] {
if let Some(v) = scalar_text(action, key) {
filtered.insert(key.to_string(), Value::String(v));
}
}
if filtered.is_empty() {
Some(format!("[web_search_call:{action_type}]"))
} else {
let json = serde_json::to_string(&Value::Object(filtered)).ok()?;
Some(format!("[web_search_call:{action_type}] {json}"))
}
}
fn web_search_call_tool_call_id(
outer: &serde_json::Map<String, Value>,
inner: Option<&serde_json::Map<String, Value>>,
) -> Option<String> {
fn scan(scope: &serde_json::Map<String, Value>) -> Option<String> {
if scope.get("type").and_then(Value::as_str) != Some("web_search_call") {
return None;
}
scalar_text(scope, "id")
}
scan(outer).or_else(|| inner.and_then(scan))
}
fn file_search_call_line_to_text(obj: &serde_json::Map<String, Value>) -> Option<String> {
if obj.get("type").and_then(Value::as_str) != Some("file_search_call") {
return None;
}
let queries: Vec<String> = obj
.get("queries")
.and_then(Value::as_array)
.map(|arr| {
arr.iter()
.filter_map(|v| v.as_str())
.map(str::trim)
.filter(|s| !s.is_empty())
.map(str::to_string)
.collect()
})
.unwrap_or_default();
if queries.is_empty() {
return None;
}
let mut filtered = serde_json::Map::new();
filtered.insert(
"queries".to_string(),
Value::Array(queries.into_iter().map(Value::String).collect()),
);
let json = serde_json::to_string(&Value::Object(filtered)).ok()?;
let mut rendered = format!("[file_search_call] {json}");
if let Some(results) = obj.get("results").and_then(Value::as_array) {
for entry in results {
if let Some(line) = file_search_result_to_text(entry) {
rendered.push('\n');
rendered.push_str(&line);
}
}
}
Some(rendered)
}
fn file_search_result_to_text(v: &Value) -> Option<String> {
let obj = v.as_object()?;
let file_id = scalar_text(obj, "file_id");
let filename = scalar_text(obj, "filename");
match (file_id, filename) {
(Some(id), Some(name)) => Some(format!("[file_search_result] {id} {name}")),
(Some(id), None) => Some(format!("[file_search_result] {id}")),
(None, Some(name)) => Some(format!("[file_search_result] {name}")),
(None, None) => None,
}
}
fn file_search_call_tool_call_id(
outer: &serde_json::Map<String, Value>,
inner: Option<&serde_json::Map<String, Value>>,
) -> Option<String> {
fn scan(scope: &serde_json::Map<String, Value>) -> Option<String> {
if scope.get("type").and_then(Value::as_str) != Some("file_search_call") {
return None;
}
scalar_text(scope, "id")
}
scan(outer).or_else(|| inner.and_then(scan))
}
fn code_interpreter_call_line_to_text(obj: &serde_json::Map<String, Value>) -> Option<String> {
if obj.get("type").and_then(Value::as_str) != Some("code_interpreter_call") {
return None;
}
let code = scalar_text(obj, "code")?;
let mut rendered = format!("[code_interpreter_call] {code}");
if let Some(outputs) = obj.get("outputs").and_then(Value::as_array) {
for entry in outputs {
if let Some(line) = code_interpreter_output_entry_to_text(entry) {
rendered.push('\n');
rendered.push_str(&line);
}
}
}
Some(rendered)
}
fn code_interpreter_output_entry_to_text(v: &Value) -> Option<String> {
let obj = v.as_object()?;
let entry_type = obj.get("type").and_then(Value::as_str)?;
match entry_type {
"logs" => {
let logs = scalar_text(obj, "logs")?;
Some(format!("[code_interpreter_logs] {logs}"))
}
"image" => {
if let Some(url) = scalar_text(obj, "url") {
if let Some(rest) = url.strip_prefix("data:") {
if let Some((media_type, _)) = rest.split_once(';') {
let media_type = media_type.trim();
if !media_type.is_empty() {
return Some(format!("[code_interpreter_image:{media_type}]"));
}
}
} else {
return Some(format!("[code_interpreter_image] {url}"));
}
}
scalar_text(obj, "file_id").map(|id| format!("[code_interpreter_image:file] {id}"))
}
_ => None,
}
}
fn code_interpreter_call_tool_call_id(
outer: &serde_json::Map<String, Value>,
inner: Option<&serde_json::Map<String, Value>>,
) -> Option<String> {
fn scan(scope: &serde_json::Map<String, Value>) -> Option<String> {
if scope.get("type").and_then(Value::as_str) != Some("code_interpreter_call") {
return None;
}
scalar_text(scope, "id")
}
scan(outer).or_else(|| inner.and_then(scan))
}
fn local_shell_call_line_to_text(obj: &serde_json::Map<String, Value>) -> Option<String> {
if obj.get("type").and_then(Value::as_str) != Some("local_shell_call") {
return None;
}
let action = obj.get("action").and_then(Value::as_object)?;
let action_type = scalar_text(action, "type")?;
let mut filtered = serde_json::Map::new();
if let Some(arr) = action.get("command").and_then(Value::as_array) {
let cmd: Vec<Value> = arr
.iter()
.filter_map(|v| v.as_str())
.map(str::trim)
.filter(|s| !s.is_empty())
.map(|s| Value::String(s.to_string()))
.collect();
if !cmd.is_empty() {
filtered.insert("command".to_string(), Value::Array(cmd));
}
}
if let Some(v) = scalar_text(action, "working_directory") {
filtered.insert("working_directory".to_string(), Value::String(v));
}
if filtered.is_empty() {
Some(format!("[local_shell_call:{action_type}]"))
} else {
let json = serde_json::to_string(&Value::Object(filtered)).ok()?;
Some(format!("[local_shell_call:{action_type}] {json}"))
}
}
fn local_shell_call_output_line_to_text(obj: &serde_json::Map<String, Value>) -> Option<String> {
if obj.get("type").and_then(Value::as_str) != Some("local_shell_call_output") {
return None;
}
let output = arguments_value_to_text(obj.get("output"))?;
Some(format!("[local_shell_call_output] {output}"))
}
fn function_call_line_to_text(obj: &serde_json::Map<String, Value>) -> Option<String> {
if obj.get("type").and_then(Value::as_str) != Some("function_call") {
return None;
}
let name = obj
.get("name")
.and_then(Value::as_str)
.map(str::trim)
.filter(|s| !s.is_empty())?;
let arguments = arguments_value_to_text(obj.get("arguments"));
Some(match arguments {
Some(args) => format!("[function_call:{name}] {args}"),
None => format!("[function_call:{name}]"),
})
}
fn custom_tool_call_line_to_text(obj: &serde_json::Map<String, Value>) -> Option<String> {
if obj.get("type").and_then(Value::as_str) != Some("custom_tool_call") {
return None;
}
let name = obj
.get("name")
.and_then(Value::as_str)
.map(str::trim)
.filter(|s| !s.is_empty())?;
let input = arguments_value_to_text(obj.get("input"));
Some(match input {
Some(input) => format!("[custom_tool_call:{name}] {input}"),
None => format!("[custom_tool_call:{name}]"),
})
}
fn function_call_output_line_to_text(obj: &serde_json::Map<String, Value>) -> Option<String> {
if obj.get("type").and_then(Value::as_str) != Some("function_call_output") {
return None;
}
let output = arguments_value_to_text(obj.get("output"))?;
Some(format!("[function_call_output] {output}"))
}
fn code_interpreter_call_output_line_to_text(
obj: &serde_json::Map<String, Value>,
) -> Option<String> {
if obj.get("type").and_then(Value::as_str) != Some("code_interpreter_call_output") {
return None;
}
let output = arguments_value_to_text(obj.get("output"))?;
Some(format!("[code_interpreter_call_output] {output}"))
}
fn custom_tool_call_output_line_to_text(obj: &serde_json::Map<String, Value>) -> Option<String> {
if obj.get("type").and_then(Value::as_str) != Some("custom_tool_call_output") {
return None;
}
let output = arguments_value_to_text(obj.get("output"))?;
Some(format!("[custom_tool_call_output] {output}"))
}
fn computer_call_line_to_text(obj: &serde_json::Map<String, Value>) -> Option<String> {
if obj.get("type").and_then(Value::as_str) != Some("computer_call") {
return None;
}
let action = obj.get("action").and_then(Value::as_object)?;
let action_type = scalar_text(action, "type")?;
let mut filtered = serde_json::Map::new();
if let Some(v) = scalar_text(action, "text") {
filtered.insert("text".to_string(), Value::String(v));
}
if let Some(arr) = action.get("keys").and_then(Value::as_array) {
let keys: Vec<Value> = arr
.iter()
.filter_map(|v| v.as_str())
.map(str::trim)
.filter(|s| !s.is_empty())
.map(|s| Value::String(s.to_string()))
.collect();
if !keys.is_empty() {
filtered.insert("keys".to_string(), Value::Array(keys));
}
}
if filtered.is_empty() {
Some(format!("[computer_call:{action_type}]"))
} else {
let json = serde_json::to_string(&Value::Object(filtered)).ok()?;
Some(format!("[computer_call:{action_type}] {json}"))
}
}
fn computer_call_output_line_to_text(obj: &serde_json::Map<String, Value>) -> Option<String> {
if obj.get("type").and_then(Value::as_str) != Some("computer_call_output") {
return None;
}
let output = obj.get("output").and_then(Value::as_object)?;
let current_url = scalar_text(output, "current_url");
let base = (|| -> Option<String> {
if let Some(url) = scalar_text(output, "image_url") {
if let Some(rest) = url.strip_prefix("data:") {
if let Some((media_type, _)) = rest.split_once(';') {
let media_type = media_type.trim();
if !media_type.is_empty() {
return Some(format!("[computer_call_output:{media_type}]"));
}
}
} else {
return Some(format!("[computer_call_output] {url}"));
}
}
scalar_text(output, "file_id")
.map(|file_id| format!("[computer_call_output:file] {file_id}"))
})();
match (base, current_url) {
(Some(b), Some(u)) => Some(format!("{b} {u}")),
(Some(b), None) => Some(b),
(None, Some(u)) => Some(format!("[computer_call_output] {u}")),
(None, None) => None,
}
}
fn reasoning_line_to_text(obj: &serde_json::Map<String, Value>) -> Option<String> {
if obj.get("type").and_then(Value::as_str) != Some("reasoning") {
return None;
}
let summary = obj.get("summary").and_then(Value::as_array)?;
let parts: Vec<String> = summary
.iter()
.filter_map(|item| {
let block = item.as_object()?;
if block.get("type").and_then(Value::as_str) != Some("summary_text") {
return None;
}
scalar_text(block, "text")
})
.collect();
if parts.is_empty() {
return None;
}
Some(format!("[reasoning] {}", parts.join("\n")))
}
fn image_generation_call_line_to_text(obj: &serde_json::Map<String, Value>) -> Option<String> {
if obj.get("type").and_then(Value::as_str) != Some("image_generation_call") {
return None;
}
let revised = scalar_text(obj, "revised_prompt")?;
Some(format!("[image_generation_call] {revised}"))
}
fn image_generation_call_tool_call_id(
outer: &serde_json::Map<String, Value>,
inner: Option<&serde_json::Map<String, Value>>,
) -> Option<String> {
fn scan(scope: &serde_json::Map<String, Value>) -> Option<String> {
if scope.get("type").and_then(Value::as_str) != Some("image_generation_call") {
return None;
}
scalar_text(scope, "id")
}
scan(outer).or_else(|| inner.and_then(scan))
}
fn mcp_call_line_to_text(obj: &serde_json::Map<String, Value>) -> Option<String> {
if obj.get("type").and_then(Value::as_str) != Some("mcp_call") {
return None;
}
let name = obj
.get("name")
.and_then(Value::as_str)
.map(str::trim)
.filter(|s| !s.is_empty())?;
let server = obj
.get("server_label")
.and_then(Value::as_str)
.map(str::trim)
.filter(|s| !s.is_empty());
let label = match server {
Some(s) => format!("{s}/{name}"),
None => name.to_string(),
};
let arguments = arguments_value_to_text(obj.get("arguments"));
let mut rendered = match arguments {
Some(args) => format!("[mcp_call:{label}] {args}"),
None => format!("[mcp_call:{label}]"),
};
if let Some(approval_request_id) = obj
.get("approval_request_id")
.and_then(Value::as_str)
.map(str::trim)
.filter(|s| !s.is_empty())
{
rendered.push('\n');
rendered.push_str(&format!(
"[mcp_call_approval_request:{label}] {approval_request_id}"
));
}
if let Some(output) = arguments_value_to_text(obj.get("output")) {
rendered.push('\n');
rendered.push_str(&format!("[mcp_call_output:{label}] {output}"));
}
if let Some(error) = arguments_value_to_text(obj.get("error")) {
rendered.push('\n');
rendered.push_str(&format!("[mcp_call_error:{label}] {error}"));
}
Some(rendered)
}
fn mcp_call_tool_call_id(
outer: &serde_json::Map<String, Value>,
inner: Option<&serde_json::Map<String, Value>>,
) -> Option<String> {
fn scan(scope: &serde_json::Map<String, Value>) -> Option<String> {
if scope.get("type").and_then(Value::as_str) != Some("mcp_call") {
return None;
}
scalar_text(scope, "id")
}
scan(outer).or_else(|| inner.and_then(scan))
}
fn mcp_approval_request_line_to_text(obj: &serde_json::Map<String, Value>) -> Option<String> {
if obj.get("type").and_then(Value::as_str) != Some("mcp_approval_request") {
return None;
}
let name = obj
.get("name")
.and_then(Value::as_str)
.map(str::trim)
.filter(|s| !s.is_empty())?;
let server = obj
.get("server_label")
.and_then(Value::as_str)
.map(str::trim)
.filter(|s| !s.is_empty());
let label = match server {
Some(s) => format!("{s}/{name}"),
None => name.to_string(),
};
let arguments = arguments_value_to_text(obj.get("arguments"));
Some(match arguments {
Some(args) => format!("[mcp_approval_request:{label}] {args}"),
None => format!("[mcp_approval_request:{label}]"),
})
}
fn mcp_approval_request_tool_call_id(
outer: &serde_json::Map<String, Value>,
inner: Option<&serde_json::Map<String, Value>>,
) -> Option<String> {
fn scan(scope: &serde_json::Map<String, Value>) -> Option<String> {
if scope.get("type").and_then(Value::as_str) != Some("mcp_approval_request") {
return None;
}
scalar_text(scope, "id")
}
scan(outer).or_else(|| inner.and_then(scan))
}
fn mcp_list_tools_line_to_text(obj: &serde_json::Map<String, Value>) -> Option<String> {
if obj.get("type").and_then(Value::as_str) != Some("mcp_list_tools") {
return None;
}
let server = obj
.get("server_label")
.and_then(Value::as_str)
.map(str::trim)
.filter(|s| !s.is_empty());
let names: Vec<String> = obj
.get("tools")
.and_then(Value::as_array)
.map(|arr| {
arr.iter()
.filter_map(|entry| entry.as_object())
.filter_map(|entry| entry.get("name").and_then(Value::as_str))
.map(str::trim)
.filter(|s| !s.is_empty())
.map(str::to_string)
.collect()
})
.unwrap_or_default();
let error = arguments_value_to_text(obj.get("error"));
let listing = if server.is_some() || !names.is_empty() {
let prefix = match server {
Some(s) => format!("[mcp_list_tools:{s}]"),
None => "[mcp_list_tools]".to_string(),
};
Some(if names.is_empty() {
prefix
} else {
format!("{prefix} {}", names.join(", "))
})
} else {
None
};
let error_line = error.map(|e| match server {
Some(s) => format!("[mcp_list_tools_error:{s}] {e}"),
None => format!("[mcp_list_tools_error] {e}"),
});
match (listing, error_line) {
(None, None) => None,
(Some(l), None) => Some(l),
(None, Some(e)) => Some(e),
(Some(l), Some(e)) => Some(format!("{l}\n{e}")),
}
}
fn mcp_approval_response_line_to_text(obj: &serde_json::Map<String, Value>) -> Option<String> {
if obj.get("type").and_then(Value::as_str) != Some("mcp_approval_response") {
return None;
}
obj.get("approval_request_id")
.and_then(Value::as_str)
.map(str::trim)
.filter(|s| !s.is_empty())?;
let approve = obj.get("approve").and_then(Value::as_bool)?;
let status = if approve { "approved" } else { "denied" };
let reason = obj
.get("reason")
.and_then(Value::as_str)
.map(str::trim)
.filter(|s| !s.is_empty());
Some(match reason {
Some(r) => format!("[mcp_approval_response:{status}] {r}"),
None => format!("[mcp_approval_response:{status}]"),
})
}
fn mcp_approval_response_tool_call_id(
outer: &serde_json::Map<String, Value>,
inner: Option<&serde_json::Map<String, Value>>,
) -> Option<String> {
fn scan(scope: &serde_json::Map<String, Value>) -> Option<String> {
if scope.get("type").and_then(Value::as_str) != Some("mcp_approval_response") {
return None;
}
scalar_text(scope, "approval_request_id")
}
scan(outer).or_else(|| inner.and_then(scan))
}
fn content_block_tool_call_id(
outer: &serde_json::Map<String, Value>,
inner: Option<&serde_json::Map<String, Value>>,
) -> Option<String> {
find_in_content_blocks(outer, inner, tool_call_id_from_block)
}
fn content_block_tool_name(
outer: &serde_json::Map<String, Value>,
inner: Option<&serde_json::Map<String, Value>>,
) -> Option<String> {
find_in_content_blocks(outer, inner, tool_name_from_block)
}
fn find_in_content_blocks(
outer: &serde_json::Map<String, Value>,
inner: Option<&serde_json::Map<String, Value>>,
f: fn(&serde_json::Map<String, Value>) -> Option<String>,
) -> Option<String> {
fn scan(
scope: &serde_json::Map<String, Value>,
f: fn(&serde_json::Map<String, Value>) -> Option<String>,
) -> Option<String> {
scope
.get("content")?
.as_array()?
.iter()
.find_map(|item| item.as_object().and_then(f))
}
scan(outer, f).or_else(|| inner.and_then(|m| scan(m, f)))
}
fn tool_call_id_from_block(obj: &serde_json::Map<String, Value>) -> Option<String> {
let extra_id_key = match obj.get("type").and_then(Value::as_str) {
Some("tool_use")
| Some("tool_result")
| Some("mcp_tool_result")
| Some("web_search_tool_result")
| Some("web_fetch_tool_result")
| Some("code_execution_tool_result")
| Some("bash_code_execution_tool_result")
| Some("function_call")
| Some("function_call_output") => None,
Some("server_tool_use") | Some("mcp_tool_use") => Some("id"),
_ => return None,
};
[
"tool_call_id",
"toolCallId",
"tool_use_id",
"toolUseId",
"call_id",
"callId",
]
.iter()
.chain(extra_id_key.iter())
.find_map(|key| scalar_text(obj, key))
}
fn tool_name_from_block(obj: &serde_json::Map<String, Value>) -> Option<String> {
match obj.get("type").and_then(Value::as_str) {
Some("tool_use")
| Some("server_tool_use")
| Some("mcp_tool_use")
| Some("function_call") => {}
_ => return None,
}
scalar_text(obj, "name")
}
fn tool_calls_array_text(obj: &serde_json::Map<String, Value>) -> Option<String> {
let arr = lookup_tool_calls_array(obj)?;
let parts: Vec<String> = arr
.iter()
.filter_map(|item| item.as_object().and_then(tool_call_entry_to_text))
.collect();
if parts.is_empty() {
None
} else {
Some(parts.join("\n"))
}
}
fn tool_calls_array_tool_name(
outer: &serde_json::Map<String, Value>,
inner: Option<&serde_json::Map<String, Value>>,
) -> Option<String> {
find_in_tool_calls_arrays(outer, inner, tool_call_entry_name)
}
fn tool_calls_array_tool_call_id(
outer: &serde_json::Map<String, Value>,
inner: Option<&serde_json::Map<String, Value>>,
) -> Option<String> {
find_in_tool_calls_arrays(outer, inner, |entry| {
[
"tool_call_id",
"toolCallId",
"tool_use_id",
"toolUseId",
"call_id",
"callId",
"id",
]
.iter()
.find_map(|key| scalar_text(entry, key))
})
}
fn legacy_function_call_text(obj: &serde_json::Map<String, Value>) -> Option<String> {
let fc = obj.get("function_call").and_then(Value::as_object)?;
tool_call_entry_to_text(fc)
}
fn legacy_function_call_tool_name(
outer: &serde_json::Map<String, Value>,
inner: Option<&serde_json::Map<String, Value>>,
) -> Option<String> {
fn scan(scope: &serde_json::Map<String, Value>) -> Option<String> {
scope
.get("function_call")
.and_then(Value::as_object)
.and_then(tool_call_entry_name)
}
scan(outer).or_else(|| inner.and_then(scan))
}
fn legacy_assistant_audio_text(obj: &serde_json::Map<String, Value>) -> Option<String> {
let audio = obj.get("audio").and_then(Value::as_object)?;
let transcript = scalar_text(audio, "transcript")?;
Some(format!("[audio] {transcript}"))
}
fn legacy_assistant_refusal_text(obj: &serde_json::Map<String, Value>) -> Option<String> {
let refusal = scalar_text(obj, "refusal")?;
Some(format!("[refusal] {refusal}"))
}
fn legacy_assistant_reasoning_content_text(obj: &serde_json::Map<String, Value>) -> Option<String> {
let reasoning =
scalar_text(obj, "reasoning_content").or_else(|| scalar_text(obj, "reasoningContent"))?;
Some(format!("[thinking] {reasoning}"))
}
fn find_in_tool_calls_arrays(
outer: &serde_json::Map<String, Value>,
inner: Option<&serde_json::Map<String, Value>>,
f: fn(&serde_json::Map<String, Value>) -> Option<String>,
) -> Option<String> {
fn scan(
scope: &serde_json::Map<String, Value>,
f: fn(&serde_json::Map<String, Value>) -> Option<String>,
) -> Option<String> {
lookup_tool_calls_array(scope)?
.iter()
.find_map(|item| item.as_object().and_then(f))
}
scan(outer, f).or_else(|| inner.and_then(|m| scan(m, f)))
}
fn lookup_tool_calls_array(obj: &serde_json::Map<String, Value>) -> Option<&Vec<Value>> {
obj.get("tool_calls")
.or_else(|| obj.get("toolCalls"))
.and_then(Value::as_array)
.filter(|arr| !arr.is_empty())
}
fn tool_call_entry_to_text(obj: &serde_json::Map<String, Value>) -> Option<String> {
let name = tool_call_entry_name(obj)?;
let arguments = tool_call_entry_arguments(obj);
Some(match arguments {
Some(args) => format!("[tool_use:{name}] {args}"),
None => format!("[tool_use:{name}]"),
})
}
fn tool_call_entry_name(obj: &serde_json::Map<String, Value>) -> Option<String> {
obj.get("function")
.and_then(Value::as_object)
.and_then(|f| scalar_text(f, "name"))
.or_else(|| scalar_text(obj, "name"))
}
fn tool_call_entry_arguments(obj: &serde_json::Map<String, Value>) -> Option<String> {
if let Some(f) = obj.get("function").and_then(Value::as_object) {
if let Some(args) = arguments_value_to_text(f.get("arguments")) {
return Some(args);
}
if let Some(args) = arguments_value_to_text(f.get("input")) {
return Some(args);
}
}
arguments_value_to_text(obj.get("arguments"))
.or_else(|| arguments_value_to_text(obj.get("input")))
}
fn arguments_value_to_text(value: Option<&Value>) -> Option<String> {
match value? {
Value::String(s) if !s.trim().is_empty() => Some(s.clone()),
Value::Number(_) | Value::Bool(_) => Some(value.unwrap().to_string()),
Value::Object(map) if !map.is_empty() => serde_json::to_string(value.unwrap()).ok(),
Value::Array(arr) if !arr.is_empty() => serde_json::to_string(value.unwrap()).ok(),
_ => None,
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn extracts_simple_string_content_with_role_prefix() {
let jsonl = "{\"role\":\"user\",\"content\":\"hello there\"}\n";
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] hello there");
assert_eq!(chunks[0].ordinal, 0);
assert_eq!(chunks[0].byte_start, 0);
assert_eq!(chunks[0].byte_end, jsonl.len());
}
#[test]
fn extracts_anthropic_content_block_array() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"text\":\"first part\"},",
"{\"type\":\"text\",\"text\":\"second part\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] first part\nsecond part");
}
#[test]
fn extracts_gemini_user_parts_array() {
let jsonl = "{\"role\":\"user\",\"parts\":[{\"text\":\"hello gemini\"}]}\n";
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] hello gemini");
assert_eq!(chunks[0].role.as_deref(), Some("user"));
}
#[test]
fn extracts_gemini_model_role_with_multi_text_parts() {
let jsonl = concat!(
"{\"role\":\"model\",\"parts\":[",
"{\"text\":\"step one\"},",
"{\"text\":\"step two\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[model] step one\nstep two");
assert_eq!(chunks[0].role.as_deref(), Some("model"));
}
#[test]
fn gemini_empty_parts_array_drops_line() {
let jsonl = "{\"role\":\"user\",\"parts\":[]}\n";
let chunks = extract_jsonl(jsonl);
assert!(
chunks.is_empty(),
"empty parts array must drop the line, got: {chunks:?}"
);
}
#[test]
fn gemini_non_array_parts_drops_line() {
let jsonl = "{\"role\":\"user\",\"parts\":\"not an array\"}\n";
let chunks = extract_jsonl(jsonl);
assert!(
chunks.is_empty(),
"non-array parts must drop the line, got: {chunks:?}"
);
}
#[test]
fn gemini_content_wins_over_parts() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":\"winner\",",
"\"parts\":[{\"text\":\"loser\"}]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] winner");
}
#[test]
fn gemini_text_wins_over_parts() {
let jsonl = concat!(
"{\"role\":\"user\",\"text\":\"winner\",",
"\"parts\":[{\"text\":\"loser\"}]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] winner");
}
#[test]
fn gemini_parts_recovers_through_message_envelope() {
let jsonl = concat!(
"{\"type\":\"user\",\"sessionId\":\"sess-1\",",
"\"message\":{\"role\":\"user\",\"parts\":[{\"text\":\"wrapped gemini\"}]}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] wrapped gemini");
assert_eq!(chunks[0].session_id.as_deref(), Some("sess-1"));
}
#[test]
fn gemini_parts_outer_wins_over_inner_message() {
let jsonl = concat!(
"{\"role\":\"user\",\"parts\":[{\"text\":\"outer wins\"}],",
"\"message\":{\"parts\":[{\"text\":\"inner loser\"}]}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] outer wins");
}
#[test]
fn gemini_parts_extracts_text_alongside_function_call() {
let jsonl = concat!(
"{\"role\":\"model\",\"parts\":[",
"{\"text\":\"calling a tool\"},",
"{\"functionCall\":{\"name\":\"search\",\"args\":{\"q\":\"x\"}}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[model] calling a tool\n[tool_use:search] {\"q\":\"x\"}"
);
}
#[test]
fn gemini_function_call_part_extracts_object_args() {
let jsonl = concat!(
"{\"role\":\"model\",\"parts\":[",
"{\"functionCall\":{\"name\":\"lookup\",\"args\":{\"zeta\":1,\"alpha\":2}}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[model] [tool_use:lookup] {\"alpha\":2,\"zeta\":1}"
);
}
#[test]
fn gemini_function_call_part_handles_scalar_and_array_args() {
let scalar = "{\"role\":\"model\",\"parts\":[{\"functionCall\":{\"name\":\"f\",\"args\":\"raw string\"}}]}\n";
assert_eq!(
extract_jsonl(scalar)[0].text,
"[model] [tool_use:f] raw string"
);
let num =
"{\"role\":\"model\",\"parts\":[{\"functionCall\":{\"name\":\"f\",\"args\":42}}]}\n";
assert_eq!(extract_jsonl(num)[0].text, "[model] [tool_use:f] 42");
let arr = "{\"role\":\"model\",\"parts\":[{\"functionCall\":{\"name\":\"f\",\"args\":[1,2,3]}}]}\n";
assert_eq!(extract_jsonl(arr)[0].text, "[model] [tool_use:f] [1,2,3]");
}
#[test]
fn gemini_function_call_part_without_args_emits_bare_prefix() {
let jsonl = concat!(
"{\"role\":\"model\",\"parts\":[",
"{\"functionCall\":{\"name\":\"ping\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[model] [tool_use:ping]");
}
#[test]
fn gemini_function_call_part_without_name_drops_part() {
let jsonl = concat!(
"{\"role\":\"model\",\"parts\":[",
"{\"text\":\"sibling text\"},",
"{\"functionCall\":{\"args\":{\"q\":\"x\"}}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[model] sibling text");
}
#[test]
fn gemini_function_response_part_extracts_object_response() {
let jsonl = concat!(
"{\"role\":\"user\",\"parts\":[",
"{\"functionResponse\":{\"name\":\"search\",",
"\"response\":{\"results\":[\"alpha\",\"beta\"],\"count\":2}}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[user] [tool_result] {\"count\":2,\"results\":[\"alpha\",\"beta\"]}"
);
}
#[test]
fn gemini_function_response_part_handles_scalar_and_array_response() {
let scalar = "{\"role\":\"user\",\"parts\":[{\"functionResponse\":{\"name\":\"f\",\"response\":\"plain reply\"}}]}\n";
assert_eq!(
extract_jsonl(scalar)[0].text,
"[user] [tool_result] plain reply"
);
let boolean = "{\"role\":\"user\",\"parts\":[{\"functionResponse\":{\"name\":\"f\",\"response\":true}}]}\n";
assert_eq!(extract_jsonl(boolean)[0].text, "[user] [tool_result] true");
let arr = "{\"role\":\"user\",\"parts\":[{\"functionResponse\":{\"name\":\"f\",\"response\":[\"a\",\"b\"]}}]}\n";
assert_eq!(
extract_jsonl(arr)[0].text,
"[user] [tool_result] [\"a\",\"b\"]"
);
}
#[test]
fn gemini_function_response_part_without_response_drops_part() {
let missing = concat!(
"{\"role\":\"user\",\"parts\":[",
"{\"text\":\"sibling\"},",
"{\"functionResponse\":{\"name\":\"f\"}}",
"]}\n"
);
assert_eq!(extract_jsonl(missing)[0].text, "[user] sibling");
let empty_obj = concat!(
"{\"role\":\"user\",\"parts\":[",
"{\"text\":\"sibling\"},",
"{\"functionResponse\":{\"name\":\"f\",\"response\":{}}}",
"]}\n"
);
assert_eq!(extract_jsonl(empty_obj)[0].text, "[user] sibling");
let blank = concat!(
"{\"role\":\"user\",\"parts\":[",
"{\"text\":\"sibling\"},",
"{\"functionResponse\":{\"name\":\"f\",\"response\":\" \"}}",
"]}\n"
);
assert_eq!(extract_jsonl(blank)[0].text, "[user] sibling");
}
#[test]
fn gemini_parts_mixed_text_call_response_join_in_array_order() {
let jsonl = concat!(
"{\"role\":\"model\",\"parts\":[",
"{\"text\":\"thinking out loud\"},",
"{\"functionCall\":{\"name\":\"search\",\"args\":{\"q\":\"x\"}}},",
"{\"functionResponse\":{\"name\":\"search\",\"response\":{\"hits\":3}}},",
"{\"text\":\"done\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[model] thinking out loud\n[tool_use:search] {\"q\":\"x\"}\n[tool_result] {\"hits\":3}\ndone"
);
}
#[test]
fn gemini_function_call_part_recovers_through_message_envelope() {
let jsonl = concat!(
"{\"type\":\"assistant\",\"sessionId\":\"sess-1\",",
"\"message\":{\"role\":\"model\",\"parts\":[",
"{\"functionCall\":{\"name\":\"wrapped\",\"args\":{\"k\":\"v\"}}}",
"]}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[model] [tool_use:wrapped] {\"k\":\"v\"}");
assert_eq!(chunks[0].session_id.as_deref(), Some("sess-1"));
}
#[test]
fn extracts_tool_and_turn_metadata_with_tool_prefix() {
let jsonl = concat!(
"{\"conversation_id\":\"sess-1\",\"turn\":\"turn-7\",\"parent_message_id\":\"turn-6\",",
"\"tool_name\":\"search\",\"created_at\":\"1700000000\",\"content\":\"tool output\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].session_id.as_deref(), Some("sess-1"));
assert_eq!(chunks[0].turn_id.as_deref(), Some("turn-7"));
assert_eq!(chunks[0].parent_turn_id.as_deref(), Some("turn-6"));
assert_eq!(chunks[0].tool_name.as_deref(), Some("search"));
assert_eq!(chunks[0].tool_call_id.as_deref(), None);
assert_eq!(chunks[0].timestamp_unix, Some(1_700_000_000));
assert_eq!(chunks[0].text, "[tool:search] tool output");
assert_eq!(chunks[0].role, None);
}
#[test]
fn openai_style_tool_role_keeps_tool_name_in_prefix() {
let jsonl = concat!(
"{\"role\":\"tool\",\"tool_name\":\"search\",",
"\"tool_call_id\":\"call-1\",\"content\":\"tool output\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[tool:search] tool output");
assert_eq!(chunks[0].role.as_deref(), Some("tool"));
assert_eq!(chunks[0].tool_name.as_deref(), Some("search"));
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call-1"));
}
#[test]
fn legacy_openai_function_role_keeps_tool_name_in_prefix() {
let jsonl = concat!(
"{\"role\":\"function\",\"name\":\"get_weather\",",
"\"content\":\"72F sunny\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[function:get_weather] 72F sunny");
assert_eq!(chunks[0].role.as_deref(), Some("function"));
assert_eq!(chunks[0].tool_name.as_deref(), Some("get_weather"));
assert_eq!(chunks[0].tool_call_id.as_deref(), None);
}
#[test]
fn legacy_openai_function_role_without_name_falls_back_to_role_prefix() {
let jsonl = "{\"role\":\"function\",\"content\":\"reply with no name\"}\n";
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[function] reply with no name");
assert_eq!(chunks[0].role.as_deref(), Some("function"));
assert_eq!(chunks[0].tool_name.as_deref(), None);
}
#[test]
fn legacy_openai_function_role_with_typed_tool_prefix_does_not_double_prefix() {
let jsonl = concat!(
"{\"role\":\"function\",\"name\":\"create_issue\",",
"\"type\":\"mcp_call\",\"server_label\":\"linear\",",
"\"arguments\":\"{\\\"title\\\":\\\"x\\\"}\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert!(
chunks[0].text.contains("[mcp_call:linear/create_issue]"),
"typed mcp_call prefix should win; got: {}",
chunks[0].text
);
assert!(
!chunks[0].text.contains("[function:create_issue]"),
"synthetic [function:NAME] prefix must be suppressed when content already carries a typed extractor prefix; got: {}",
chunks[0].text
);
}
#[test]
fn anthropic_tool_use_id_alias_populates_tool_call_id() {
let jsonl = concat!(
"{\"role\":\"tool\",\"tool_name\":\"search\",",
"\"tool_use_id\":\"toolu_01abc\",\"content\":\"tool output\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("toolu_01abc"));
}
#[test]
fn anthropic_tool_use_id_camel_case_alias_populates_tool_call_id() {
let jsonl = concat!(
"{\"role\":\"tool\",\"toolName\":\"search\",",
"\"toolUseId\":\"toolu_02def\",\"content\":\"tool output\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("toolu_02def"));
}
#[test]
fn tool_call_id_wins_over_tool_use_id_on_same_object() {
let jsonl = concat!(
"{\"role\":\"tool\",\"tool_name\":\"search\",",
"\"tool_call_id\":\"call-canonical\",\"tool_use_id\":\"toolu_ignored\",",
"\"content\":\"tool output\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call-canonical"));
}
#[test]
fn tool_use_id_from_inner_message_envelope_populates_tool_call_id() {
let jsonl = concat!(
"{\"type\":\"tool_result\",\"sessionId\":\"sess-claude\",",
"\"message\":{\"role\":\"tool\",\"toolUseId\":\"toolu_inner\",",
"\"content\":\"tool output\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("toolu_inner"));
assert_eq!(chunks[0].session_id.as_deref(), Some("sess-claude"));
}
#[test]
fn extracts_role_prefixed_message_with_timestamp() {
let jsonl = "{\"role\":\"assistant\",\"timestamp\":1700000001,\"content\":\"hello\"}\n";
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].role.as_deref(), Some("assistant"));
assert_eq!(chunks[0].timestamp_unix, Some(1_700_000_001));
assert_eq!(chunks[0].text, "[assistant] hello");
}
#[test]
fn extracts_from_alternate_text_fields() {
let jsonl = "{\"text\":\"alpha\"}\n{\"message\":\"beta\"}\n{\"body\":\"gamma\"}\n";
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 3);
assert_eq!(chunks[0].text, "alpha");
assert_eq!(chunks[1].text, "beta");
assert_eq!(chunks[2].text, "gamma");
}
#[test]
fn byte_ranges_point_to_source_lines() {
let line_a = "{\"text\":\"aaa\"}\n";
let line_b = "{\"text\":\"bbb\"}\n";
let jsonl = format!("{line_a}{line_b}");
let chunks = extract_jsonl(&jsonl);
assert_eq!(chunks.len(), 2);
assert_eq!(chunks[0].byte_start, 0);
assert_eq!(chunks[0].byte_end, line_a.len());
assert_eq!(chunks[1].byte_start, line_a.len());
assert_eq!(chunks[1].byte_end, line_a.len() + line_b.len());
}
#[test]
fn skips_blank_and_malformed_and_empty_lines() {
let jsonl = "\n{not json}\n{\"role\":\"u\",\"content\":\"\"}\n{\"text\":\"ok\"}\n";
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "ok");
assert_eq!(chunks[0].ordinal, 0);
}
#[test]
fn returns_empty_for_empty_input() {
assert!(extract_jsonl("").is_empty());
}
#[test]
fn ignores_lines_without_extractable_fields() {
let jsonl = "{\"timestamp\":1234}\n{\"foo\":\"bar\"}\n";
assert!(extract_jsonl(jsonl).is_empty());
}
#[test]
fn camel_case_aliases_populate_session_turn_tool_and_timestamp() {
let jsonl = concat!(
"{\"conversationId\":\"sess-2\",\"turnId\":\"turn-9\",",
"\"parentMessageId\":\"turn-8\",\"toolName\":\"lookup\",\"toolCallId\":\"call-2\",\"createdAt\":1700000123,",
"\"role\":\"tool\",\"content\":\"camel output\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].session_id.as_deref(), Some("sess-2"));
assert_eq!(chunks[0].turn_id.as_deref(), Some("turn-9"));
assert_eq!(chunks[0].parent_turn_id.as_deref(), Some("turn-8"));
assert_eq!(chunks[0].tool_name.as_deref(), Some("lookup"));
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call-2"));
assert_eq!(chunks[0].timestamp_unix, Some(1_700_000_123));
assert_eq!(chunks[0].text, "[tool:lookup] camel output");
}
#[test]
fn session_id_camel_case_thread_id_alias_populates_session() {
let jsonl = "{\"threadId\":\"thr-1\",\"messageId\":\"msg-1\",\"content\":\"hi\"}\n";
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].session_id.as_deref(), Some("thr-1"));
assert_eq!(chunks[0].turn_id.as_deref(), Some("msg-1"));
}
#[test]
fn snake_case_keys_take_precedence_over_camel_case() {
let jsonl = concat!(
"{\"session_id\":\"snake\",\"sessionId\":\"camel\",",
"\"turn_id\":\"t-snake\",\"turnId\":\"t-camel\",",
"\"parent_turn_id\":\"p-snake\",\"parentTurnId\":\"p-camel\",",
"\"tool_name\":\"tn-snake\",\"toolName\":\"tn-camel\",",
"\"created_at\":1700000200,\"createdAt\":1700000999,",
"\"content\":\"prefer snake\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].session_id.as_deref(), Some("snake"));
assert_eq!(chunks[0].turn_id.as_deref(), Some("t-snake"));
assert_eq!(chunks[0].parent_turn_id.as_deref(), Some("p-snake"));
assert_eq!(chunks[0].tool_name.as_deref(), Some("tn-snake"));
assert_eq!(chunks[0].timestamp_unix, Some(1_700_000_200));
}
#[test]
fn missing_role_produces_unprefixed_text() {
let jsonl = "{\"content\":\"no role here\"}\n";
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "no role here");
}
#[test]
fn nested_message_envelope_string_content() {
let jsonl = concat!(
"{\"type\":\"user\",\"sessionId\":\"sess-claude\",\"timestamp\":1700000300,",
"\"message\":{\"role\":\"user\",\"content\":\"where is the lantern\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] where is the lantern");
assert_eq!(chunks[0].role.as_deref(), Some("user"));
assert_eq!(chunks[0].session_id.as_deref(), Some("sess-claude"));
assert_eq!(chunks[0].timestamp_unix, Some(1_700_000_300));
}
#[test]
fn nested_message_envelope_block_array_content() {
let jsonl = concat!(
"{\"type\":\"assistant\",\"sessionId\":\"sess-claude\",",
"\"message\":{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"text\":\"first part\"},",
"{\"type\":\"text\",\"text\":\"second part\"}",
"]}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] first part\nsecond part");
assert_eq!(chunks[0].role.as_deref(), Some("assistant"));
}
#[test]
fn nested_message_envelope_picks_up_inner_metadata() {
let jsonl = concat!(
"{\"type\":\"assistant\",\"message\":{\"role\":\"assistant\",",
"\"id\":\"msg_01\",\"messageId\":\"msg_01\",\"toolName\":\"search\",",
"\"toolCallId\":\"call_x\",\"sessionId\":\"sess-inner\",",
"\"createdAt\":1700000400,\"content\":\"inner result\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].session_id.as_deref(), Some("sess-inner"));
assert_eq!(chunks[0].turn_id.as_deref(), Some("msg_01"));
assert_eq!(chunks[0].tool_name.as_deref(), Some("search"));
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_x"));
assert_eq!(chunks[0].timestamp_unix, Some(1_700_000_400));
}
#[test]
fn outer_metadata_wins_over_envelope_inner_metadata() {
let jsonl = concat!(
"{\"sessionId\":\"outer\",\"turnId\":\"t-outer\",\"role\":\"user\",",
"\"message\":{\"sessionId\":\"inner\",\"turnId\":\"t-inner\",",
"\"role\":\"assistant\",\"content\":\"hi\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].session_id.as_deref(), Some("outer"));
assert_eq!(chunks[0].turn_id.as_deref(), Some("t-outer"));
assert_eq!(chunks[0].role.as_deref(), Some("user"));
assert_eq!(chunks[0].text, "[user] hi");
}
#[test]
fn string_typed_message_field_still_works() {
let jsonl = "{\"message\":\"plain string fallback\"}\n";
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "plain string fallback");
assert_eq!(chunks[0].role, None);
}
#[test]
fn outer_text_wins_over_envelope_content() {
let jsonl = concat!(
"{\"text\":\"outer wins\",",
"\"message\":{\"role\":\"assistant\",\"content\":\"inner ignored\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] outer wins");
assert_eq!(chunks[0].role.as_deref(), Some("assistant"));
}
#[test]
fn envelope_with_no_extractable_content_drops() {
let jsonl = "{\"type\":\"assistant\",\"message\":{\"role\":\"assistant\"}}\n";
assert!(extract_jsonl(jsonl).is_empty());
}
#[test]
fn extracts_project_from_primary_alias() {
let jsonl = "{\"project\":\"lantern\",\"content\":\"hi\"}\n";
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].project.as_deref(), Some("lantern"));
}
#[test]
fn extracts_project_from_each_alias() {
for (key, expected) in [
("project_id", "lp-1"),
("projectId", "lp-2"),
("repo", "diogenes/lantern"),
("repository", "https://github.com/diogenes/lantern"),
] {
let jsonl = format!("{{\"{key}\":\"{expected}\",\"content\":\"hi\"}}\n");
let chunks = extract_jsonl(&jsonl);
assert_eq!(chunks.len(), 1, "alias {key} should produce a chunk");
assert_eq!(
chunks[0].project.as_deref(),
Some(expected),
"alias {key} did not populate project"
);
}
}
#[test]
fn project_outer_envelope_wins_over_inner_message() {
let jsonl = concat!(
"{\"project\":\"outer-project\",",
"\"message\":{\"role\":\"assistant\",\"project\":\"inner-project\",",
"\"content\":\"hi\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].project.as_deref(), Some("outer-project"));
}
#[test]
fn project_falls_back_to_inner_message_when_outer_missing() {
let jsonl = concat!(
"{\"type\":\"assistant\",",
"\"message\":{\"role\":\"assistant\",\"project\":\"inner-project\",",
"\"content\":\"hi\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].project.as_deref(), Some("inner-project"));
}
#[test]
fn project_primary_key_wins_over_other_aliases_on_same_object() {
let jsonl = concat!(
"{\"project\":\"primary\",\"project_id\":\"pid\",\"repo\":\"r\",",
"\"repository\":\"https://example.test/r\",\"content\":\"hi\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].project.as_deref(), Some("primary"));
}
#[test]
fn project_absent_when_no_alias_present() {
let jsonl = "{\"content\":\"hi\"}\n";
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].project, None);
}
#[test]
fn extracts_user_from_primary_alias() {
let jsonl = "{\"user\":\"alice\",\"content\":\"hi\"}\n";
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].user.as_deref(), Some("alice"));
}
#[test]
fn role_scoped_name_populates_user_for_participant_roles() {
for role in ["user", "assistant", "system", "developer"] {
let jsonl = format!("{{\"role\":\"{role}\",\"name\":\"alice\",\"content\":\"hi\"}}\n");
let chunks = extract_jsonl(&jsonl);
assert_eq!(chunks.len(), 1, "role {role} should produce a chunk");
assert_eq!(
chunks[0].user.as_deref(),
Some("alice"),
"role {role} should route name to user"
);
assert_eq!(
chunks[0].tool_name, None,
"role {role} should not misroute name to tool_name"
);
}
}
#[test]
fn role_scoped_name_also_folds_participant_name_into_role_prefix() {
for role in ["user", "assistant", "system", "developer"] {
let jsonl = format!("{{\"role\":\"{role}\",\"name\":\"alice\",\"content\":\"hi\"}}\n");
let chunks = extract_jsonl(&jsonl);
assert_eq!(chunks.len(), 1, "role {role} should produce a chunk");
assert_eq!(chunks[0].text, format!("[{role}:alice] hi"));
}
}
#[test]
fn explicit_user_aliases_still_beat_name_for_participant_roles() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"name\":\"participant-name\",",
"\"user\":\"primary-user\",\"author\":\"author-name\",\"content\":\"hi\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].user.as_deref(), Some("primary-user"));
assert_eq!(chunks[0].tool_name, None);
}
#[test]
fn role_scoped_name_stays_tool_name_for_tool_like_roles_or_missing_role() {
for jsonl in [
"{\"role\":\"tool\",\"name\":\"search\",\"content\":\"done\"}\n",
"{\"role\":\"function\",\"name\":\"get_weather\",\"content\":\"done\"}\n",
"{\"name\":\"ambiguous\",\"content\":\"done\"}\n",
] {
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].user, None);
assert!(chunks[0].tool_name.is_some());
}
}
#[test]
fn extracts_user_from_each_alias() {
for (key, expected) in [
("user_id", "u-1"),
("userId", "u-2"),
("author", "Alice Example"),
("participant", "p-3"),
] {
let jsonl = format!("{{\"{key}\":\"{expected}\",\"content\":\"hi\"}}\n");
let chunks = extract_jsonl(&jsonl);
assert_eq!(chunks.len(), 1, "alias {key} should produce a chunk");
assert_eq!(
chunks[0].user.as_deref(),
Some(expected),
"alias {key} did not populate user"
);
}
}
#[test]
fn user_outer_envelope_wins_over_inner_message() {
let jsonl = concat!(
"{\"user\":\"outer-user\",",
"\"message\":{\"role\":\"assistant\",\"user\":\"inner-user\",",
"\"content\":\"hi\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].user.as_deref(), Some("outer-user"));
}
#[test]
fn user_falls_back_to_inner_message_when_outer_missing() {
let jsonl = concat!(
"{\"type\":\"assistant\",",
"\"message\":{\"role\":\"assistant\",\"user\":\"inner-user\",",
"\"content\":\"hi\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].user.as_deref(), Some("inner-user"));
}
#[test]
fn user_primary_key_wins_over_other_aliases_on_same_object() {
let jsonl = concat!(
"{\"user\":\"primary\",\"user_id\":\"uid\",\"userId\":\"uidc\",",
"\"author\":\"author-name\",\"participant\":\"p\",\"content\":\"hi\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].user.as_deref(), Some("primary"));
}
#[test]
fn user_absent_when_no_alias_present() {
let jsonl = "{\"content\":\"hi\"}\n";
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].user, None);
}
#[test]
fn extracts_topic_from_primary_alias() {
let jsonl = "{\"topic\":\"onboarding\",\"content\":\"hi\"}\n";
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].topic.as_deref(), Some("onboarding"));
}
#[test]
fn extracts_topic_from_each_alias() {
for (key, expected) in [
("topic_id", "tp-1"),
("topicId", "tp-2"),
("subject", "Re: contract review"),
("category", "support"),
] {
let jsonl = format!("{{\"{key}\":\"{expected}\",\"content\":\"hi\"}}\n");
let chunks = extract_jsonl(&jsonl);
assert_eq!(chunks.len(), 1, "alias {key} should produce a chunk");
assert_eq!(
chunks[0].topic.as_deref(),
Some(expected),
"alias {key} did not populate topic"
);
}
}
#[test]
fn topic_outer_envelope_wins_over_inner_message() {
let jsonl = concat!(
"{\"topic\":\"outer-topic\",",
"\"message\":{\"role\":\"assistant\",\"topic\":\"inner-topic\",",
"\"content\":\"hi\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].topic.as_deref(), Some("outer-topic"));
}
#[test]
fn topic_falls_back_to_inner_message_when_outer_missing() {
let jsonl = concat!(
"{\"type\":\"assistant\",",
"\"message\":{\"role\":\"assistant\",\"topic\":\"inner-topic\",",
"\"content\":\"hi\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].topic.as_deref(), Some("inner-topic"));
}
#[test]
fn topic_primary_key_wins_over_other_aliases_on_same_object() {
let jsonl = concat!(
"{\"topic\":\"primary\",\"topic_id\":\"tid\",\"topicId\":\"tidc\",",
"\"subject\":\"subj\",\"category\":\"cat\",\"content\":\"hi\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].topic.as_deref(), Some("primary"));
}
#[test]
fn topic_absent_when_no_alias_present() {
let jsonl = "{\"content\":\"hi\"}\n";
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].topic, None);
}
#[test]
fn extracts_thread_from_primary_alias() {
let jsonl = "{\"thread\":\"telegram:ops\",\"content\":\"hi\"}\n";
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].thread.as_deref(), Some("telegram:ops"));
}
#[test]
fn extracts_thread_from_each_alias() {
for (key, expected) in [("thread_id", "thr-1"), ("threadId", "thr-2")] {
let jsonl = format!("{{\"{key}\":\"{expected}\",\"content\":\"hi\"}}\n");
let chunks = extract_jsonl(&jsonl);
assert_eq!(chunks.len(), 1, "alias {key} should produce a chunk");
assert_eq!(
chunks[0].thread.as_deref(),
Some(expected),
"alias {key} did not populate thread"
);
}
}
#[test]
fn thread_outer_envelope_wins_over_inner_message() {
let jsonl = concat!(
"{\"thread\":\"outer-thread\",",
"\"message\":{\"role\":\"assistant\",\"thread\":\"inner-thread\",",
"\"content\":\"hi\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].thread.as_deref(), Some("outer-thread"));
}
#[test]
fn thread_falls_back_to_inner_message_when_outer_missing() {
let jsonl = concat!(
"{\"type\":\"assistant\",",
"\"message\":{\"role\":\"assistant\",\"thread\":\"inner-thread\",",
"\"content\":\"hi\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].thread.as_deref(), Some("inner-thread"));
}
#[test]
fn thread_primary_key_wins_over_other_aliases_on_same_object() {
let jsonl = concat!(
"{\"thread\":\"primary\",\"thread_id\":\"tid\",\"threadId\":\"tidc\",",
"\"content\":\"hi\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].thread.as_deref(), Some("primary"));
}
#[test]
fn thread_absent_when_no_alias_present() {
let jsonl = "{\"content\":\"hi\"}\n";
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].thread, None);
}
#[test]
fn structured_arguments_object_serialized_as_compact_json() {
let jsonl =
"{\"role\":\"tool\",\"tool_name\":\"search\",\"arguments\":{\"q\":\"hello\"}}\n";
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[tool:search] {\"q\":\"hello\"}");
assert_eq!(chunks[0].tool_name.as_deref(), Some("search"));
}
#[test]
fn structured_input_array_serialized_as_compact_json() {
let jsonl = "{\"role\":\"assistant\",\"input\":[1,2,3]}\n";
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] [1,2,3]");
}
#[test]
fn structured_input_object_keys_serialized_in_sorted_order() {
let jsonl = "{\"input\":{\"zeta\":1,\"alpha\":2}}\n";
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "{\"alpha\":2,\"zeta\":1}");
}
#[test]
fn string_typed_arguments_field_still_works() {
let jsonl = "{\"arguments\":\"plain string fallback\"}\n";
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "plain string fallback");
}
#[test]
fn string_typed_input_field_still_works() {
let jsonl = "{\"input\":\"plain input string\"}\n";
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "plain input string");
}
#[test]
fn empty_arguments_object_alone_drops_line() {
let jsonl = "{\"arguments\":{}}\n{\"input\":[]}\n";
assert!(extract_jsonl(jsonl).is_empty());
}
#[test]
fn empty_arguments_falls_through_to_later_fallback() {
let jsonl = "{\"arguments\":{},\"input\":{\"q\":\"hi\"}}\n";
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "{\"q\":\"hi\"}");
}
#[test]
fn content_still_wins_over_structured_arguments() {
let jsonl = "{\"role\":\"user\",\"content\":\"hi\",\"arguments\":{\"q\":\"ignored\"}}\n";
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] hi");
}
#[test]
fn nested_message_envelope_structured_input_picked_up() {
let jsonl = concat!(
"{\"type\":\"tool\",\"message\":{\"role\":\"tool\",\"tool_name\":\"search\",",
"\"input\":{\"q\":\"hello\"}}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[tool:search] {\"q\":\"hello\"}");
assert_eq!(chunks[0].role.as_deref(), Some("tool"));
assert_eq!(chunks[0].tool_name.as_deref(), Some("search"));
}
#[test]
fn outer_structured_arguments_wins_over_inner_arguments() {
let jsonl = concat!(
"{\"arguments\":{\"q\":\"outer\"},",
"\"message\":{\"role\":\"tool\",\"arguments\":{\"q\":\"inner\"}}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[tool] {\"q\":\"outer\"}");
}
#[test]
fn thread_id_alias_populates_both_session_id_and_thread() {
let jsonl = "{\"thread_id\":\"thr-shared\",\"content\":\"hi\"}\n";
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].session_id.as_deref(), Some("thr-shared"));
assert_eq!(chunks[0].thread.as_deref(), Some("thr-shared"));
}
#[test]
fn tool_result_block_with_nested_text_block_array_is_extracted() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"tool_result\",\"tool_use_id\":\"toolu_01\",\"content\":[",
"{\"type\":\"text\",\"text\":\"search hit one\"},",
"{\"type\":\"text\",\"text\":\"search hit two\"}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] search hit one\nsearch hit two");
}
#[test]
fn tool_result_block_with_nested_direct_string_content_is_extracted() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"tool_result\",\"tool_use_id\":\"toolu_02\",\"content\":\"plain result\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] plain result");
}
#[test]
fn tool_result_block_with_empty_nested_content_drops() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"tool_result\",\"content\":[]}",
"]}\n"
);
assert!(extract_jsonl(jsonl).is_empty());
}
#[test]
fn tool_use_block_with_structured_input_object_is_extracted() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"tool_use\",\"id\":\"toolu_01\",\"name\":\"search\",",
"\"input\":{\"q\":\"hello\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [tool_use:search] {\"q\":\"hello\"}"
);
}
#[test]
fn tool_use_block_with_structured_input_array_is_extracted() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"tool_use\",\"name\":\"batch\",\"input\":[1,2,3]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] [tool_use:batch] [1,2,3]");
}
#[test]
fn tool_use_block_with_string_input_is_extracted() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"tool_use\",\"name\":\"echo\",\"input\":\"plain string arg\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [tool_use:echo] plain string arg"
);
}
#[test]
fn tool_use_block_with_missing_input_keeps_prefix() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"tool_use\",\"name\":\"ping\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] [tool_use:ping]");
}
#[test]
fn tool_use_block_with_empty_input_object_keeps_prefix() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"tool_use\",\"name\":\"ping\",\"input\":{}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] [tool_use:ping]");
}
#[test]
fn tool_use_block_input_object_keys_serialized_in_sorted_order() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"tool_use\",\"name\":\"search\",\"input\":{\"zeta\":1,\"alpha\":2}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [tool_use:search] {\"alpha\":2,\"zeta\":1}"
);
}
#[test]
fn tool_use_block_without_name_drops() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"tool_use\",\"input\":{\"q\":\"hello\"}}",
"]}\n"
);
assert!(extract_jsonl(jsonl).is_empty());
}
#[test]
fn tool_use_block_with_blank_name_drops() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"tool_use\",\"name\":\" \",\"input\":{\"q\":\"hello\"}}",
"]}\n"
);
assert!(extract_jsonl(jsonl).is_empty());
}
#[test]
fn tool_use_block_with_text_field_still_prefers_text() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"tool_use\",\"name\":\"search\",\"text\":\"direct text wins\",",
"\"input\":{\"q\":\"ignored\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] direct text wins");
}
#[test]
fn text_and_tool_use_blocks_interleave_in_join_order() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"text\":\"let me search\"},",
"{\"type\":\"tool_use\",\"name\":\"search\",\"input\":{\"q\":\"hello\"}},",
"{\"type\":\"text\",\"text\":\"done\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] let me search\n[tool_use:search] {\"q\":\"hello\"}\ndone"
);
}
#[test]
fn non_tool_use_typed_block_without_text_or_content_still_drops() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"something_else\",\"name\":\"x\",\"input\":{\"q\":\"hi\"}}",
"]}\n"
);
assert!(extract_jsonl(jsonl).is_empty());
}
#[test]
fn server_tool_use_block_with_structured_input_is_extracted() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"server_tool_use\",\"id\":\"srvtoolu_01\",\"name\":\"web_search\",",
"\"input\":{\"query\":\"lantern docs\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [server_tool_use:web_search] {\"query\":\"lantern docs\"}"
);
assert_eq!(chunks[0].tool_name.as_deref(), Some("web_search"));
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("srvtoolu_01"));
}
#[test]
fn server_tool_use_block_input_object_keys_serialized_in_sorted_order() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"server_tool_use\",\"name\":\"web_search\",",
"\"input\":{\"zeta\":1,\"alpha\":2}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [server_tool_use:web_search] {\"alpha\":2,\"zeta\":1}"
);
}
#[test]
fn server_tool_use_block_with_missing_input_keeps_prefix() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"server_tool_use\",\"name\":\"web_search\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] [server_tool_use:web_search]");
assert_eq!(chunks[0].tool_name.as_deref(), Some("web_search"));
}
#[test]
fn server_tool_use_block_with_empty_input_keeps_prefix() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"server_tool_use\",\"name\":\"web_search\",\"input\":{}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] [server_tool_use:web_search]");
}
#[test]
fn server_tool_use_block_without_name_drops() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"server_tool_use\",\"id\":\"srvtoolu_x\",\"input\":{\"q\":\"hi\"}}",
"]}\n"
);
assert!(extract_jsonl(jsonl).is_empty());
}
#[test]
fn server_tool_use_block_with_blank_name_drops() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"server_tool_use\",\"name\":\" \",\"input\":{\"q\":\"hi\"}}",
"]}\n"
);
assert!(extract_jsonl(jsonl).is_empty());
}
#[test]
fn server_tool_use_block_with_text_field_still_prefers_text() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"server_tool_use\",\"name\":\"web_search\",",
"\"text\":\"direct text wins\",\"input\":{\"q\":\"ignored\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] direct text wins");
}
#[test]
fn text_and_server_tool_use_blocks_interleave_in_join_order() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"text\":\"let me search the web\"},",
"{\"type\":\"server_tool_use\",\"name\":\"web_search\",",
"\"input\":{\"query\":\"hello\"}},",
"{\"type\":\"text\",\"text\":\"done\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] let me search the web\n[server_tool_use:web_search] {\"query\":\"hello\"}\ndone"
);
}
#[test]
fn nested_server_tool_use_block_id_populates_tool_call_id_when_outer_missing() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"server_tool_use\",\"id\":\"srvtoolu_nested\",",
"\"name\":\"web_search\",\"input\":{\"q\":\"hi\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("srvtoolu_nested"));
assert_eq!(chunks[0].tool_name.as_deref(), Some("web_search"));
}
#[test]
fn outer_tool_call_id_wins_over_nested_server_tool_use_block() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"tool_call_id\":\"outer-call\",\"content\":[",
"{\"type\":\"server_tool_use\",\"id\":\"srvtoolu_nested\",",
"\"name\":\"web_search\",\"input\":{\"q\":\"hi\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("outer-call"));
}
#[test]
fn outer_tool_name_wins_over_nested_server_tool_use_block() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"tool_name\":\"outer-tool\",\"content\":[",
"{\"type\":\"server_tool_use\",\"name\":\"web_search\",",
"\"input\":{\"q\":\"hi\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_name.as_deref(), Some("outer-tool"));
}
#[test]
fn tool_result_block_with_is_error_true_prefixes_text_with_tool_error() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"tool_result\",\"tool_use_id\":\"toolu_01\",\"is_error\":true,",
"\"content\":\"command failed\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] [tool_error] command failed");
}
#[test]
fn tool_result_block_with_is_error_true_and_nested_text_block_array() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"tool_result\",\"tool_use_id\":\"toolu_02\",\"is_error\":true,",
"\"content\":[",
"{\"type\":\"text\",\"text\":\"stderr line one\"},",
"{\"type\":\"text\",\"text\":\"stderr line two\"}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[user] [tool_error] stderr line one\nstderr line two"
);
}
#[test]
fn tool_result_block_without_is_error_is_unchanged() {
let jsonl_no_flag = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"tool_result\",\"tool_use_id\":\"toolu_03\",",
"\"content\":\"plain result\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl_no_flag);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] plain result");
let jsonl_false = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"tool_result\",\"tool_use_id\":\"toolu_04\",\"is_error\":false,",
"\"content\":\"plain result\"}",
"]}",
"\n"
);
let chunks = extract_jsonl(jsonl_false);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] plain result");
}
#[test]
fn tool_result_error_block_with_empty_nested_content_drops() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"tool_result\",\"is_error\":true,\"content\":[]}",
"]}\n"
);
assert!(extract_jsonl(jsonl).is_empty());
}
#[test]
fn tool_result_error_block_text_field_still_wins() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"tool_result\",\"is_error\":true,\"text\":\"direct text wins\",",
"\"content\":\"ignored\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] direct text wins");
}
#[test]
fn tool_result_error_block_interleaves_with_other_blocks_in_join_order() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"text\",\"text\":\"prior context\"},",
"{\"type\":\"tool_result\",\"is_error\":true,\"content\":\"command failed\"},",
"{\"type\":\"text\",\"text\":\"trailing note\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[user] prior context\n[tool_error] command failed\ntrailing note"
);
}
#[test]
fn non_tool_result_block_with_is_error_flag_does_not_trigger_prefix() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"text\",\"is_error\":true,\"text\":\"this is just text\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] this is just text");
}
#[test]
fn nested_tool_use_block_id_populates_tool_call_id_when_outer_missing() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"tool_use\",\"tool_use_id\":\"toolu_nested\",\"name\":\"search\",",
"\"input\":{\"q\":\"hi\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("toolu_nested"));
assert_eq!(chunks[0].tool_name.as_deref(), Some("search"));
}
#[test]
fn nested_tool_result_block_tool_use_id_populates_tool_call_id() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"tool_result\",\"tool_use_id\":\"toolu_from_result\",",
"\"content\":\"output\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("toolu_from_result"));
assert_eq!(chunks[0].tool_name, None);
}
#[test]
fn nested_tool_call_id_recognises_all_six_aliases() {
for alias in [
"tool_call_id",
"toolCallId",
"tool_use_id",
"toolUseId",
"call_id",
"callId",
] {
let jsonl = format!(
concat!(
"{{\"role\":\"user\",\"content\":[",
"{{\"type\":\"tool_result\",\"{alias}\":\"toolu_alias\",",
"\"content\":\"output\"}}",
"]}}\n"
),
alias = alias
);
let chunks = extract_jsonl(&jsonl);
assert_eq!(chunks.len(), 1, "alias {alias} should produce a chunk");
assert_eq!(
chunks[0].tool_call_id.as_deref(),
Some("toolu_alias"),
"alias {alias} did not populate tool_call_id"
);
}
}
#[test]
fn outer_tool_call_id_wins_over_nested_content_block() {
let jsonl = concat!(
"{\"role\":\"user\",\"tool_call_id\":\"outer-call\",\"content\":[",
"{\"type\":\"tool_result\",\"tool_use_id\":\"nested-call\",",
"\"content\":\"output\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("outer-call"));
}
#[test]
fn outer_tool_name_wins_over_nested_tool_use_block() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"tool_name\":\"outer-tool\",\"content\":[",
"{\"type\":\"tool_use\",\"name\":\"nested-tool\",\"input\":{\"q\":\"hi\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_name.as_deref(), Some("outer-tool"));
}
#[test]
fn inner_message_tool_call_id_wins_over_nested_content_block() {
let jsonl = concat!(
"{\"type\":\"tool_result\",",
"\"message\":{\"role\":\"tool\",\"toolUseId\":\"inner-call\",\"content\":[",
"{\"type\":\"tool_result\",\"tool_use_id\":\"nested-call\",",
"\"content\":\"output\"}",
"]}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("inner-call"));
}
#[test]
fn nested_tool_call_id_only_picks_tool_use_or_tool_result_blocks() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"tool_use_id\":\"toolu_should_not_match\",",
"\"text\":\"hi\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_call_id, None);
}
#[test]
fn nested_tool_name_only_picks_tool_use_blocks() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"tool_result\",\"name\":\"should_not_match\",",
"\"tool_use_id\":\"toolu_x\",\"content\":\"output\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_name, None);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("toolu_x"));
}
#[test]
fn nested_metadata_falls_back_to_inner_message_content() {
let jsonl = concat!(
"{\"type\":\"tool_result\",\"sessionId\":\"sess-claude\",",
"\"message\":{\"role\":\"tool\",\"content\":[",
"{\"type\":\"tool_result\",\"tool_use_id\":\"toolu_deep\",",
"\"content\":\"output\"}",
"]}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("toolu_deep"));
assert_eq!(chunks[0].session_id.as_deref(), Some("sess-claude"));
}
#[test]
fn openai_tool_calls_array_renders_as_searchable_text_when_no_content() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"tool_calls\":[",
"{\"id\":\"call_abc\",\"type\":\"function\",",
"\"function\":{\"name\":\"search\",\"arguments\":\"{\\\"q\\\":\\\"hello\\\"}\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [tool_use:search] {\"q\":\"hello\"}"
);
assert_eq!(chunks[0].tool_name.as_deref(), Some("search"));
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_abc"));
}
#[test]
fn openai_tool_calls_array_camel_case_alias_is_recognised() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"toolCalls\":[",
"{\"id\":\"call_camel\",\"type\":\"function\",",
"\"function\":{\"name\":\"lookup\",\"arguments\":\"{\\\"k\\\":1}\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] [tool_use:lookup] {\"k\":1}");
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_camel"));
}
#[test]
fn openai_tool_calls_array_arguments_object_serialized_as_compact_json() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"tool_calls\":[",
"{\"id\":\"call_obj\",\"type\":\"function\",",
"\"function\":{\"name\":\"search\",\"arguments\":{\"zeta\":1,\"alpha\":2}}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [tool_use:search] {\"alpha\":2,\"zeta\":1}"
);
}
#[test]
fn openai_tool_calls_array_flat_entry_shape_is_supported() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"tool_calls\":[",
"{\"id\":\"call_flat\",\"name\":\"echo\",\"arguments\":\"hello\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] [tool_use:echo] hello");
assert_eq!(chunks[0].tool_name.as_deref(), Some("echo"));
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_flat"));
}
#[test]
fn openai_tool_calls_array_multiple_entries_join_with_newline() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"tool_calls\":[",
"{\"id\":\"call_1\",\"type\":\"function\",",
"\"function\":{\"name\":\"first\",\"arguments\":\"{}\"}},",
"{\"id\":\"call_2\",\"type\":\"function\",",
"\"function\":{\"name\":\"second\",\"arguments\":\"{\\\"q\\\":\\\"x\\\"}\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [tool_use:first] {}\n[tool_use:second] {\"q\":\"x\"}"
);
assert_eq!(chunks[0].tool_name.as_deref(), Some("first"));
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_1"));
}
#[test]
fn openai_tool_calls_array_entry_without_name_is_skipped() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"tool_calls\":[",
"{\"id\":\"call_x\",\"type\":\"function\",",
"\"function\":{\"arguments\":\"{}\"}}",
"]}\n"
);
assert!(extract_jsonl(jsonl).is_empty());
}
#[test]
fn openai_tool_calls_array_skips_nameless_but_keeps_named_entries() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"tool_calls\":[",
"{\"id\":\"call_no_name\",\"type\":\"function\",",
"\"function\":{\"arguments\":\"{}\"}},",
"{\"id\":\"call_named\",\"type\":\"function\",",
"\"function\":{\"name\":\"keep\",\"arguments\":\"{}\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] [tool_use:keep] {}");
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_no_name"));
assert_eq!(chunks[0].tool_name.as_deref(), Some("keep"));
}
#[test]
fn empty_tool_calls_array_alone_drops_line() {
let jsonl = "{\"role\":\"assistant\",\"tool_calls\":[]}\n";
assert!(extract_jsonl(jsonl).is_empty());
}
#[test]
fn empty_tool_calls_falls_through_to_later_fallback() {
let jsonl = "{\"role\":\"assistant\",\"text\":\"trailing prose\",\"tool_calls\":[]}\n";
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] trailing prose");
}
#[test]
fn content_text_still_wins_over_tool_calls_array() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":\"let me check\",\"tool_calls\":[",
"{\"id\":\"call_meta\",\"type\":\"function\",",
"\"function\":{\"name\":\"search\",\"arguments\":\"{}\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] let me check");
assert_eq!(chunks[0].tool_name.as_deref(), Some("search"));
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_meta"));
}
#[test]
fn outer_tool_name_wins_over_tool_calls_array_entry() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"tool_name\":\"outer-tool\",\"tool_calls\":[",
"{\"id\":\"call_x\",\"type\":\"function\",",
"\"function\":{\"name\":\"inner-tool\",\"arguments\":\"{}\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_name.as_deref(), Some("outer-tool"));
}
#[test]
fn outer_tool_call_id_wins_over_tool_calls_array_entry() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"tool_call_id\":\"outer-call\",\"tool_calls\":[",
"{\"id\":\"inner-call\",\"type\":\"function\",",
"\"function\":{\"name\":\"search\",\"arguments\":\"{}\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("outer-call"));
}
#[test]
fn inner_message_envelope_tool_calls_array_is_picked_up() {
let jsonl = concat!(
"{\"type\":\"assistant\",\"sessionId\":\"sess-openai\",",
"\"message\":{\"role\":\"assistant\",\"tool_calls\":[",
"{\"id\":\"call_inner\",\"type\":\"function\",",
"\"function\":{\"name\":\"search\",\"arguments\":\"{\\\"q\\\":\\\"hi\\\"}\"}}",
"]}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [tool_use:search] {\"q\":\"hi\"}"
);
assert_eq!(chunks[0].session_id.as_deref(), Some("sess-openai"));
assert_eq!(chunks[0].tool_name.as_deref(), Some("search"));
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_inner"));
}
#[test]
fn inner_message_envelope_tool_name_wins_over_outer_tool_calls_array() {
let jsonl = concat!(
"{\"type\":\"assistant\",\"tool_calls\":[",
"{\"id\":\"call_outer\",\"type\":\"function\",",
"\"function\":{\"name\":\"outer-array-tool\",\"arguments\":\"{}\"}}",
"],",
"\"message\":{\"role\":\"assistant\",\"tool_name\":\"inner-direct\",",
"\"content\":\"hi\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_name.as_deref(), Some("inner-direct"));
}
#[test]
fn tool_calls_array_does_not_override_content_block_tool_name() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"tool_use\",\"name\":\"block-tool\",\"input\":{}}",
"],\"tool_calls\":[",
"{\"id\":\"call_x\",\"type\":\"function\",",
"\"function\":{\"name\":\"array-tool\",\"arguments\":\"{}\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_name.as_deref(), Some("block-tool"));
}
#[test]
fn tool_calls_entry_id_is_recovered_when_outer_missing() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"tool_calls\":[",
"{\"id\":\"call_only_id\",\"type\":\"function\",",
"\"function\":{\"name\":\"search\",\"arguments\":\"{}\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_only_id"));
}
#[test]
fn tool_calls_entry_arguments_string_passes_through_unparsed() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"tool_calls\":[",
"{\"id\":\"call_str\",\"type\":\"function\",",
"\"function\":{\"name\":\"search\",\"arguments\":\"{\\\"q\\\":\\\"needle in haystack\\\"}\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert!(chunks[0].text.contains("needle in haystack"));
}
#[test]
fn tool_calls_entry_with_empty_arguments_keeps_prefix() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"tool_calls\":[",
"{\"id\":\"call_empty\",\"type\":\"function\",",
"\"function\":{\"name\":\"ping\",\"arguments\":{}}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] [tool_use:ping]");
}
#[test]
fn outer_text_field_on_content_block_still_wins_over_nested_content() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"text\":\"outer text\",\"content\":[",
"{\"type\":\"text\",\"text\":\"ignored\"}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] outer text");
}
#[test]
fn anthropic_thinking_block_renders_with_thinking_prefix() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"thinking\",\"thinking\":\"reasoning trace\",",
"\"signature\":\"sig-abc\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] [thinking] reasoning trace");
}
#[test]
fn thinking_block_with_blank_field_drops_no_placeholder() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"thinking\",\"thinking\":\" \"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert!(chunks.is_empty(), "blank thinking field should drop block");
}
#[test]
fn thinking_block_missing_field_drops_no_placeholder() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"thinking\",\"signature\":\"sig-abc\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert!(
chunks.is_empty(),
"missing thinking field should drop block"
);
}
#[test]
fn thinking_block_interleaves_with_other_blocks_in_join_order() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"thinking\",\"thinking\":\"first I should reason\"},",
"{\"type\":\"text\",\"text\":\"now answering\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [thinking] first I should reason\nnow answering"
);
}
#[test]
fn thinking_block_text_field_still_wins_over_thinking_field() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"thinking\",\"text\":\"explicit text\",",
"\"thinking\":\"reasoning ignored\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] explicit text");
}
#[test]
fn non_thinking_block_with_thinking_field_does_not_trigger_prefix() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"thinking\":\"should not surface\",",
"\"text\":\"plain text\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] plain text");
}
#[test]
fn redacted_thinking_block_is_not_extracted() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"redacted_thinking\",\"data\":\"encrypted-blob\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert!(
chunks.is_empty(),
"redacted_thinking block should not be extracted"
);
}
#[test]
fn openai_reasoning_text_block_renders_with_thinking_prefix() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"reasoning_text\",\"text\":\"weigh the tradeoffs carefully\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [thinking] weigh the tradeoffs carefully"
);
}
#[test]
fn reasoning_text_block_with_blank_text_drops_no_placeholder() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"reasoning_text\",\"text\":\" \"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert!(
chunks.is_empty(),
"blank reasoning_text field should drop block"
);
}
#[test]
fn reasoning_text_block_missing_field_drops_no_placeholder() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"reasoning_text\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert!(
chunks.is_empty(),
"missing reasoning_text text field should drop block"
);
}
#[test]
fn reasoning_text_block_interleaves_with_other_blocks_in_join_order() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"reasoning_text\",\"text\":\"first I should reason\"},",
"{\"type\":\"text\",\"text\":\"now answering\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [thinking] first I should reason\nnow answering"
);
}
#[test]
fn non_reasoning_text_block_with_text_field_keeps_no_prefix() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"text\":\"plain text\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] plain text");
}
#[test]
fn openai_refusal_block_renders_with_refusal_prefix() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"refusal\",\"refusal\":\"I can't help with that request\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [refusal] I can't help with that request"
);
}
#[test]
fn refusal_block_with_blank_field_drops_no_placeholder() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"refusal\",\"refusal\":\" \"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert!(chunks.is_empty(), "blank refusal field should drop block");
}
#[test]
fn refusal_block_missing_field_drops_no_placeholder() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"refusal\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert!(chunks.is_empty(), "missing refusal field should drop block");
}
#[test]
fn refusal_block_interleaves_with_other_blocks_in_join_order() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"text\":\"let me think about that\"},",
"{\"type\":\"refusal\",\"refusal\":\"actually I can't help\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] let me think about that\n[refusal] actually I can't help"
);
}
#[test]
fn refusal_block_wins_over_stray_text_field() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"refusal\",\"refusal\":\"refusal payload\",\"text\":\"stray text\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] [refusal] refusal payload");
}
#[test]
fn non_refusal_block_with_refusal_field_keeps_no_prefix() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"text\":\"plain text\",\"refusal\":\"unrelated\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] plain text");
}
#[test]
fn output_text_with_url_citation_renders_text_plus_citation_line() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"output_text\",\"text\":\"The capital of France is Paris.\",",
"\"annotations\":[",
"{\"type\":\"url_citation\",\"url\":\"https://example.com/france\",",
"\"title\":\"France facts\",\"start_index\":0,\"end_index\":24}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] The capital of France is Paris.\n[url_citation] https://example.com/france France facts"
);
}
#[test]
fn output_text_url_citation_without_title_drops_title_segment() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"output_text\",\"text\":\"see source\",\"annotations\":[",
"{\"type\":\"url_citation\",\"url\":\"https://example.com/a\"}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] see source\n[url_citation] https://example.com/a"
);
}
#[test]
fn output_text_with_multiple_url_citations_joins_in_array_order() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"output_text\",\"text\":\"compare sources\",\"annotations\":[",
"{\"type\":\"url_citation\",\"url\":\"https://a.example/\",\"title\":\"Alpha\"},",
"{\"type\":\"url_citation\",\"url\":\"https://b.example/\",\"title\":\"Beta\"}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] compare sources\n[url_citation] https://a.example/ Alpha\n[url_citation] https://b.example/ Beta"
);
}
#[test]
fn output_text_with_file_citation_renders_file_id_and_filename() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"output_text\",\"text\":\"refer to the docs\",\"annotations\":[",
"{\"type\":\"file_citation\",\"file_id\":\"file_abc123\",",
"\"filename\":\"handbook.pdf\",\"index\":0}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] refer to the docs\n[file_citation] file_abc123 handbook.pdf"
);
}
#[test]
fn output_text_file_citation_with_only_file_id_renders_id_only() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"output_text\",\"text\":\"see file\",\"annotations\":[",
"{\"type\":\"file_citation\",\"file_id\":\"file_only\"}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] see file\n[file_citation] file_only"
);
}
#[test]
fn output_text_file_citation_with_only_filename_renders_filename_only() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"output_text\",\"text\":\"see file\",\"annotations\":[",
"{\"type\":\"file_citation\",\"filename\":\"only-name.pdf\"}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] see file\n[file_citation] only-name.pdf"
);
}
#[test]
fn output_text_file_citation_with_no_anchors_is_skipped() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"output_text\",\"text\":\"plain body\",\"annotations\":[",
"{\"type\":\"file_citation\",\"index\":2}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] plain body");
}
#[test]
fn output_text_without_annotations_renders_plain_text() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"output_text\",\"text\":\"plain body\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] plain body");
}
#[test]
fn output_text_with_empty_annotations_array_renders_plain_text() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"output_text\",\"text\":\"plain body\",\"annotations\":[]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] plain body");
}
#[test]
fn output_text_with_only_unknown_annotation_types_renders_plain_text() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"output_text\",\"text\":\"plain body\",\"annotations\":[",
"{\"type\":\"future_citation\",\"foo\":\"bar\"},",
"{\"no_type\":true}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] plain body");
}
#[test]
fn output_text_url_citation_missing_url_is_skipped() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"output_text\",\"text\":\"body\",\"annotations\":[",
"{\"type\":\"url_citation\",\"title\":\"only title\"}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] body");
}
#[test]
fn output_text_annotations_interleave_with_other_blocks_in_join_order() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"text\":\"prefix line\"},",
"{\"type\":\"output_text\",\"text\":\"middle body\",\"annotations\":[",
"{\"type\":\"url_citation\",\"url\":\"https://mid.example/\"}",
"]},",
"{\"type\":\"text\",\"text\":\"trailing line\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] prefix line\nmiddle body\n[url_citation] https://mid.example/\ntrailing line"
);
}
#[test]
fn non_output_text_block_with_annotations_unaffected() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"text\":\"plain text\",\"annotations\":[",
"{\"type\":\"url_citation\",\"url\":\"https://example.com/\"}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] plain text");
}
#[test]
fn output_text_url_and_file_citations_render_in_array_order() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"output_text\",\"text\":\"mixed sources\",\"annotations\":[",
"{\"type\":\"url_citation\",\"url\":\"https://web.example/\",\"title\":\"Web\"},",
"{\"type\":\"file_citation\",\"file_id\":\"file_x\",\"filename\":\"doc.pdf\"}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] mixed sources\n[url_citation] https://web.example/ Web\n[file_citation] file_x doc.pdf"
);
}
#[test]
fn output_text_container_file_citation_renders_file_id_and_filename() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"output_text\",\"text\":\"see the generated plot\",\"annotations\":[",
"{\"type\":\"container_file_citation\",\"container_id\":\"cntr_abc\",",
"\"file_id\":\"cfile_xyz\",\"filename\":\"plot.png\",",
"\"start_index\":0,\"end_index\":24}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] see the generated plot\n[container_file_citation] cfile_xyz plot.png"
);
assert!(!chunks[0].text.contains("cntr_abc"));
}
#[test]
fn output_text_container_file_citation_with_only_file_id_renders_id_only() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"output_text\",\"text\":\"see file\",\"annotations\":[",
"{\"type\":\"container_file_citation\",\"container_id\":\"cntr_only\",",
"\"file_id\":\"cfile_only\"}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] see file\n[container_file_citation] cfile_only"
);
assert!(!chunks[0].text.contains("cntr_only"));
}
#[test]
fn output_text_container_file_citation_with_only_filename_renders_filename_only() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"output_text\",\"text\":\"see file\",\"annotations\":[",
"{\"type\":\"container_file_citation\",\"container_id\":\"cntr_x\",",
"\"filename\":\"only-name.csv\"}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] see file\n[container_file_citation] only-name.csv"
);
assert!(!chunks[0].text.contains("cntr_x"));
}
#[test]
fn output_text_container_file_citation_with_no_anchors_is_skipped() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"output_text\",\"text\":\"plain body\",\"annotations\":[",
"{\"type\":\"container_file_citation\",\"container_id\":\"cntr_only\",",
"\"start_index\":0,\"end_index\":10}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] plain body");
assert!(!chunks[0].text.contains("cntr_only"));
assert!(!chunks[0].text.contains("container_file_citation"));
}
#[test]
fn output_text_container_file_citation_interleaves_with_other_citations() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"output_text\",\"text\":\"mixed sources\",\"annotations\":[",
"{\"type\":\"url_citation\",\"url\":\"https://web.example/\",\"title\":\"Web\"},",
"{\"type\":\"container_file_citation\",\"container_id\":\"cntr_mid\",",
"\"file_id\":\"cfile_mid\",\"filename\":\"chart.svg\"},",
"{\"type\":\"file_citation\",\"file_id\":\"file_end\",\"filename\":\"doc.pdf\"}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] mixed sources\n\
[url_citation] https://web.example/ Web\n\
[container_file_citation] cfile_mid chart.svg\n\
[file_citation] file_end doc.pdf"
);
assert!(!chunks[0].text.contains("cntr_mid"));
}
#[test]
fn container_file_citation_prefix_distinct_from_file_citation() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"output_text\",\"text\":\"body\",\"annotations\":[",
"{\"type\":\"container_file_citation\",\"file_id\":\"cfile_only\"}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert!(
chunks[0]
.text
.contains("[container_file_citation] cfile_only")
);
assert!(!chunks[0].text.contains("[file_citation] "));
}
#[test]
fn non_output_text_block_with_container_file_citation_unaffected() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"text\":\"plain text\",\"annotations\":[",
"{\"type\":\"container_file_citation\",\"file_id\":\"cfile_x\",",
"\"filename\":\"plot.png\"}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] plain text");
assert!(!chunks[0].text.contains("container_file_citation"));
}
#[test]
fn top_level_output_text_line_with_url_citation_renders_text_plus_citation_line() {
let jsonl = concat!(
"{\"type\":\"output_text\",",
"\"text\":\"The capital of France is Paris.\",",
"\"annotations\":[",
"{\"type\":\"url_citation\",\"url\":\"https://example.com/france\",",
"\"title\":\"France facts\",\"start_index\":0,\"end_index\":24}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"The capital of France is Paris.\n[url_citation] https://example.com/france France facts"
);
}
#[test]
fn top_level_output_text_line_with_file_citation_renders_text_plus_citation_line() {
let jsonl = concat!(
"{\"type\":\"output_text\",\"text\":\"refer to the docs\",",
"\"annotations\":[",
"{\"type\":\"file_citation\",\"file_id\":\"file_abc123\",",
"\"filename\":\"handbook.pdf\",\"index\":0}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"refer to the docs\n[file_citation] file_abc123 handbook.pdf"
);
}
#[test]
fn top_level_output_text_line_with_container_file_citation_renders_text_plus_citation_line() {
let jsonl = concat!(
"{\"type\":\"output_text\",\"text\":\"see the generated plot\",",
"\"annotations\":[",
"{\"type\":\"container_file_citation\",\"container_id\":\"cntr_abc\",",
"\"file_id\":\"cfile_xyz\",\"filename\":\"plot.png\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"see the generated plot\n[container_file_citation] cfile_xyz plot.png"
);
assert!(!chunks[0].text.contains("cntr_abc"));
}
#[test]
fn top_level_output_text_line_without_annotations_renders_plain_text() {
let jsonl = "{\"type\":\"output_text\",\"text\":\"plain body\"}\n";
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "plain body");
}
#[test]
fn top_level_output_text_line_with_empty_annotations_renders_plain_text() {
let jsonl = "{\"type\":\"output_text\",\"text\":\"plain body\",\"annotations\":[]}\n";
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "plain body");
}
#[test]
fn top_level_output_text_line_with_only_unknown_annotation_types_renders_plain_text() {
let jsonl = concat!(
"{\"type\":\"output_text\",\"text\":\"plain body\",\"annotations\":[",
"{\"type\":\"future_citation\",\"foo\":\"bar\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "plain body");
}
#[test]
fn top_level_non_output_text_line_with_annotations_drops_citation_line() {
let jsonl = concat!(
"{\"type\":\"text\",\"text\":\"plain text\",\"annotations\":[",
"{\"type\":\"url_citation\",\"url\":\"https://example.com/\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "plain text");
assert!(!chunks[0].text.contains("[url_citation]"));
}
#[test]
fn top_level_output_text_line_preserves_role_prefix_when_present() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"type\":\"output_text\",",
"\"text\":\"answer body\",\"annotations\":[",
"{\"type\":\"url_citation\",\"url\":\"https://example.com/a\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] answer body\n[url_citation] https://example.com/a"
);
}
#[test]
fn top_level_output_text_line_with_content_field_still_wins_content_path() {
let jsonl = concat!(
"{\"type\":\"output_text\",\"content\":\"from content\",",
"\"text\":\"from text\",\"annotations\":[",
"{\"type\":\"url_citation\",\"url\":\"https://example.com/\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "from content");
assert!(!chunks[0].text.contains("from text"));
assert!(!chunks[0].text.contains("[url_citation]"));
}
#[test]
fn anthropic_text_with_char_location_citation_renders_text_plus_citation_line() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"text\":\"the answer is 42\",\"citations\":[",
"{\"type\":\"char_location\",\"cited_text\":\"The Answer to Life is 42.\",",
"\"document_index\":0,\"document_title\":\"Hitchhiker's Guide\",",
"\"start_char_index\":100,\"end_char_index\":124}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] the answer is 42\n[citation:char_location] Hitchhiker's Guide The Answer to Life is 42."
);
}
#[test]
fn anthropic_text_citation_with_only_document_title_drops_cited_text_segment() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"text\":\"body\",\"citations\":[",
"{\"type\":\"char_location\",\"document_index\":0,",
"\"document_title\":\"Doc Only\"}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] body\n[citation:char_location] Doc Only"
);
}
#[test]
fn anthropic_text_citation_with_only_cited_text_drops_title_segment() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"text\":\"body\",\"citations\":[",
"{\"type\":\"char_location\",\"cited_text\":\"untitled quote\"}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] body\n[citation:char_location] untitled quote"
);
}
#[test]
fn anthropic_text_with_page_location_citation_renders_with_distinct_prefix() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"text\":\"see page 3\",\"citations\":[",
"{\"type\":\"page_location\",\"cited_text\":\"page 3 says X\",",
"\"document_title\":\"Report Q3\",",
"\"start_page_number\":3,\"end_page_number\":4}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] see page 3\n[citation:page_location] Report Q3 page 3 says X"
);
}
#[test]
fn anthropic_text_with_content_block_location_citation_renders_with_distinct_prefix() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"text\":\"see block 2\",\"citations\":[",
"{\"type\":\"content_block_location\",\"cited_text\":\"block 2 says Y\",",
"\"document_title\":\"Structured Doc\",",
"\"start_block_index\":2,\"end_block_index\":3}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] see block 2\n[citation:content_block_location] Structured Doc block 2 says Y"
);
}
#[test]
fn anthropic_text_with_multiple_citations_joins_in_array_order() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"text\":\"two sources\",\"citations\":[",
"{\"type\":\"char_location\",\"cited_text\":\"first quote\",",
"\"document_title\":\"Doc A\"},",
"{\"type\":\"page_location\",\"cited_text\":\"second quote\",",
"\"document_title\":\"Doc B\"}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] two sources\n[citation:char_location] Doc A first quote\n[citation:page_location] Doc B second quote"
);
}
#[test]
fn anthropic_text_citation_with_no_anchors_is_skipped() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"text\":\"plain body\",\"citations\":[",
"{\"type\":\"char_location\",\"document_index\":0,",
"\"start_char_index\":100,\"end_char_index\":200}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] plain body");
}
#[test]
fn anthropic_text_without_citations_renders_plain_text() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"text\":\"plain body\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] plain body");
}
#[test]
fn anthropic_text_with_empty_citations_array_renders_plain_text() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"text\":\"plain body\",\"citations\":[]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] plain body");
}
#[test]
fn anthropic_text_with_only_unknown_citation_types_renders_plain_text() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"text\":\"plain body\",\"citations\":[",
"{\"type\":\"future_citation\",\"foo\":\"bar\"},",
"{\"no_type\":true}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] plain body");
}
#[test]
fn anthropic_text_citations_interleave_with_other_blocks_in_join_order() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"text\":\"prefix line\"},",
"{\"type\":\"text\",\"text\":\"middle body\",\"citations\":[",
"{\"type\":\"char_location\",\"cited_text\":\"mid quote\",",
"\"document_title\":\"Mid Doc\"}",
"]},",
"{\"type\":\"text\",\"text\":\"trailing line\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] prefix line\nmiddle body\n[citation:char_location] Mid Doc mid quote\ntrailing line"
);
}
#[test]
fn non_text_block_with_citations_unaffected() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"output_text\",\"text\":\"plain body\",\"citations\":[",
"{\"type\":\"char_location\",\"document_title\":\"Doc\",",
"\"cited_text\":\"q\"}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] plain body");
}
#[test]
fn anthropic_text_citations_and_openai_annotations_dont_overlap() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"text\":\"anthropic body\",\"citations\":[",
"{\"type\":\"char_location\",\"document_title\":\"A\",",
"\"cited_text\":\"qa\"}",
"]},",
"{\"type\":\"output_text\",\"text\":\"openai body\",\"annotations\":[",
"{\"type\":\"url_citation\",\"url\":\"https://b.example/\",\"title\":\"B\"}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] anthropic body\n[citation:char_location] A qa\nopenai body\n[url_citation] https://b.example/ B"
);
}
#[test]
fn anthropic_web_search_result_location_citation_renders_with_all_anchors() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"text\":\"the latest stable\",\"citations\":[",
"{\"type\":\"web_search_result_location\",",
"\"url\":\"https://rustc.example/release-notes\",",
"\"title\":\"Rust 1.99 release notes\",",
"\"cited_text\":\"Rust 1.99 is the latest stable.\",",
"\"encrypted_index\":\"opaqueblob==\"}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] the latest stable\n[citation:web_search_result_location] https://rustc.example/release-notes Rust 1.99 release notes Rust 1.99 is the latest stable."
);
assert!(!chunks[0].text.contains("opaqueblob"));
}
#[test]
fn anthropic_web_search_result_location_citation_with_only_url() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"text\":\"body\",\"citations\":[",
"{\"type\":\"web_search_result_location\",",
"\"url\":\"https://example.com/page\"}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] body\n[citation:web_search_result_location] https://example.com/page"
);
}
#[test]
fn anthropic_web_search_result_location_citation_with_only_title() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"text\":\"body\",\"citations\":[",
"{\"type\":\"web_search_result_location\",",
"\"title\":\"Some Web Page\"}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] body\n[citation:web_search_result_location] Some Web Page"
);
}
#[test]
fn anthropic_web_search_result_location_citation_with_only_cited_text() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"text\":\"body\",\"citations\":[",
"{\"type\":\"web_search_result_location\",",
"\"cited_text\":\"a quoted excerpt\"}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] body\n[citation:web_search_result_location] a quoted excerpt"
);
}
#[test]
fn anthropic_web_search_result_location_with_no_anchors_drops_and_falls_through() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"text\":\"plain body\",\"citations\":[",
"{\"type\":\"web_search_result_location\",",
"\"encrypted_index\":\"opaqueblob==\"}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] plain body");
assert!(!chunks[0].text.contains("opaqueblob"));
}
#[test]
fn anthropic_search_result_location_citation_renders_with_all_anchors() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"text\":\"per the docs\",\"citations\":[",
"{\"type\":\"search_result_location\",",
"\"source\":\"docs/intro.md\",",
"\"title\":\"Introduction\",",
"\"cited_text\":\"Lantern is a local-first memory engine.\",",
"\"start_block_index\":3,\"end_block_index\":4}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] per the docs\n[citation:search_result_location] docs/intro.md Introduction Lantern is a local-first memory engine."
);
assert!(!chunks[0].text.contains("start_block_index"));
assert!(!chunks[0].text.contains("end_block_index"));
}
#[test]
fn anthropic_search_result_location_citation_with_only_source() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"text\":\"body\",\"citations\":[",
"{\"type\":\"search_result_location\",",
"\"source\":\"docs/intro.md\"}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] body\n[citation:search_result_location] docs/intro.md"
);
}
#[test]
fn anthropic_search_result_location_with_no_anchors_drops_and_falls_through() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"text\":\"plain body\",\"citations\":[",
"{\"type\":\"search_result_location\",",
"\"start_block_index\":3,\"end_block_index\":4}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] plain body");
}
#[test]
fn anthropic_mixed_citation_types_join_in_array_order() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"text\":\"three cites\",\"citations\":[",
"{\"type\":\"char_location\",",
"\"document_title\":\"Doc One\",\"cited_text\":\"q1\"},",
"{\"type\":\"web_search_result_location\",",
"\"url\":\"https://example.com/w\",\"title\":\"Web Two\"},",
"{\"type\":\"search_result_location\",",
"\"source\":\"docs/three.md\",\"cited_text\":\"q3\"}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] three cites\n[citation:char_location] Doc One q1\n[citation:web_search_result_location] https://example.com/w Web Two\n[citation:search_result_location] docs/three.md q3"
);
}
#[test]
fn image_block_with_url_source_renders_with_image_prefix_and_url() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"image\",\"source\":{\"type\":\"url\",",
"\"url\":\"https://example.com/cat.png\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] [image] https://example.com/cat.png");
}
#[test]
fn image_block_with_base64_source_renders_with_media_type() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"image\",\"source\":{\"type\":\"base64\",",
"\"media_type\":\"image/png\",\"data\":\"AAAA\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] [image:image/png]");
assert!(!chunks[0].text.contains("AAAA"));
}
#[test]
fn image_block_url_wins_over_media_type() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"image\",\"source\":{\"type\":\"url\",",
"\"url\":\"https://example.com/x.jpg\",\"media_type\":\"image/jpeg\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] [image] https://example.com/x.jpg");
}
#[test]
fn image_block_with_no_url_or_media_type_drops() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"image\",\"source\":{\"type\":\"base64\",\"data\":\"AAAA\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert!(
chunks.is_empty(),
"image block with no url/media_type should drop"
);
}
#[test]
fn image_block_with_missing_source_drops() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"image\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert!(chunks.is_empty(), "image block with no source should drop");
}
#[test]
fn image_block_text_field_wins_over_image_prefix() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"image\",\"text\":\"caption: a cat\",",
"\"source\":{\"type\":\"url\",\"url\":\"https://example.com/cat.png\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] caption: a cat");
}
#[test]
fn image_block_interleaves_with_text_in_join_order() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"text\",\"text\":\"what is this?\"},",
"{\"type\":\"image\",\"source\":{\"type\":\"url\",",
"\"url\":\"https://example.com/mystery.png\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[user] what is this?\n[image] https://example.com/mystery.png"
);
}
#[test]
fn non_image_block_with_source_field_keeps_no_image_prefix() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"text\",\"text\":\"plain text\",",
"\"source\":{\"type\":\"url\",\"url\":\"https://example.com/x.png\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] plain text");
}
#[test]
fn image_block_with_blank_url_falls_through_to_media_type() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"image\",\"source\":{\"type\":\"base64\",",
"\"url\":\" \",\"media_type\":\"image/jpeg\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] [image:image/jpeg]");
}
#[test]
fn input_image_block_with_https_url_renders_with_input_image_prefix() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"input_image\",\"image_url\":\"https://example.com/cat.png\",",
"\"detail\":\"high\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[user] [input_image] https://example.com/cat.png"
);
assert!(!chunks[0].text.contains("high"));
}
#[test]
fn input_image_block_with_data_url_surfaces_media_type_not_base64() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"input_image\",",
"\"image_url\":\"data:image/png;base64,iVBORw0KAAAABLOBNOISE\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] [input_image:image/png]");
assert!(!chunks[0].text.contains("iVBORw0KAAAABLOBNOISE"));
assert!(!chunks[0].text.contains("base64"));
}
#[test]
fn input_image_block_with_file_id_renders_with_file_prefix() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"input_image\",\"file_id\":\"file_abc123\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] [input_image:file] file_abc123");
}
#[test]
fn input_image_block_image_url_wins_over_file_id() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"input_image\",\"image_url\":\"https://example.com/x.png\",",
"\"file_id\":\"file_abc\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[user] [input_image] https://example.com/x.png"
);
assert!(!chunks[0].text.contains("file_abc"));
}
#[test]
fn input_image_block_with_no_anchors_drops() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"input_image\",\"detail\":\"low\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert!(
chunks.is_empty(),
"input_image block with no anchors should drop"
);
}
#[test]
fn input_image_block_with_malformed_data_url_falls_through_to_file_id() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"input_image\",",
"\"image_url\":\"data:GARBAGENOSEMI\",\"file_id\":\"file_fallback\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] [input_image:file] file_fallback");
assert!(!chunks[0].text.contains("GARBAGENOSEMI"));
}
#[test]
fn input_image_block_with_blank_data_url_media_type_falls_through() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"input_image\",",
"\"image_url\":\"data: ;base64,AAAA\",\"file_id\":\"file_x\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] [input_image:file] file_x");
assert!(!chunks[0].text.contains("AAAA"));
}
#[test]
fn input_image_block_text_field_wins_over_input_image_prefix() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"input_image\",\"text\":\"caption: a cat\",",
"\"image_url\":\"https://example.com/cat.png\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] caption: a cat");
}
#[test]
fn input_image_block_interleaves_with_text_in_join_order() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"input_text\",\"text\":\"what is this?\"},",
"{\"type\":\"input_image\",\"image_url\":\"https://example.com/mystery.png\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[user] what is this?\n[input_image] https://example.com/mystery.png"
);
}
#[test]
fn non_input_image_block_with_image_url_field_keeps_no_input_image_prefix() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"text\",\"text\":\"plain text\",",
"\"image_url\":\"https://example.com/x.png\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] plain text");
}
#[test]
fn input_image_block_does_not_collide_with_anthropic_image_block() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"image\",\"source\":{\"type\":\"url\",",
"\"url\":\"https://example.com/anthropic.png\"}},",
"{\"type\":\"input_image\",\"image_url\":\"https://example.com/openai.png\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[user] [image] https://example.com/anthropic.png\n[input_image] https://example.com/openai.png"
);
}
#[test]
fn chat_completions_image_url_block_with_https_url_renders_with_image_url_prefix() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"image_url\",\"image_url\":",
"{\"url\":\"https://example.com/cat.png\",\"detail\":\"high\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[user] [image_url] https://example.com/cat.png"
);
assert!(!chunks[0].text.contains("high"));
}
#[test]
fn chat_completions_image_url_block_with_data_url_surfaces_media_type_not_base64() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"image_url\",\"image_url\":",
"{\"url\":\"data:image/png;base64,iVBORw0KAAAABLOBNOISE\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] [image_url:image/png]");
assert!(!chunks[0].text.contains("iVBORw0KAAAABLOBNOISE"));
assert!(!chunks[0].text.contains("base64"));
}
#[test]
fn chat_completions_image_url_block_with_no_url_drops() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"image_url\",\"image_url\":{\"detail\":\"low\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert!(
chunks.is_empty(),
"image_url block with no usable url should drop"
);
}
#[test]
fn chat_completions_image_url_block_with_missing_image_url_object_drops() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"image_url\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert!(
chunks.is_empty(),
"image_url block with no image_url object should drop"
);
}
#[test]
fn chat_completions_image_url_block_with_malformed_data_url_drops() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"image_url\",\"image_url\":",
"{\"url\":\"data:GARBAGENOSEMI\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert!(
chunks.is_empty(),
"image_url block with malformed data URL should drop"
);
}
#[test]
fn chat_completions_image_url_block_with_blank_data_url_media_type_drops() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"image_url\",\"image_url\":",
"{\"url\":\"data: ;base64,AAAA\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert!(
chunks.is_empty(),
"image_url block with blank media_type should drop"
);
}
#[test]
fn chat_completions_image_url_block_text_field_wins_over_image_url_prefix() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"image_url\",\"text\":\"caption: a cat\",",
"\"image_url\":{\"url\":\"https://example.com/cat.png\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] caption: a cat");
}
#[test]
fn chat_completions_image_url_block_interleaves_with_text_in_join_order() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"text\",\"text\":\"what is this?\"},",
"{\"type\":\"image_url\",\"image_url\":",
"{\"url\":\"https://example.com/mystery.png\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[user] what is this?\n[image_url] https://example.com/mystery.png"
);
}
#[test]
fn non_image_url_block_with_image_url_object_keeps_no_image_url_prefix() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"text\",\"text\":\"plain text\",",
"\"image_url\":{\"url\":\"https://example.com/x.png\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] plain text");
}
#[test]
fn chat_completions_image_url_does_not_collide_with_responses_input_image() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"image_url\",\"image_url\":",
"{\"url\":\"https://example.com/legacy.png\"}},",
"{\"type\":\"input_image\",\"image_url\":\"https://example.com/responses.png\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[user] [image_url] https://example.com/legacy.png\n[input_image] https://example.com/responses.png"
);
}
#[test]
fn chat_completions_image_url_block_with_flat_image_url_string_drops() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"image_url\",\"image_url\":\"https://example.com/flat.png\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert!(
chunks.is_empty(),
"image_url block with flat-string image_url should drop"
);
}
#[test]
fn input_file_block_with_https_url_renders_with_input_file_prefix() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"input_file\",\"file_url\":\"https://example.com/report.pdf\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[user] [input_file] https://example.com/report.pdf"
);
}
#[test]
fn input_file_block_with_filename_and_file_data_renders_filename() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"input_file\",\"filename\":\"draconomicon.pdf\",",
"\"file_data\":\"data:application/pdf;base64,JVBERi0xLjQK_BLOB_NEVER_INDEX_ME\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] [input_file] draconomicon.pdf");
assert!(!chunks[0].text.contains("JVBERi0xLjQK_BLOB_NEVER_INDEX_ME"));
assert!(!chunks[0].text.contains("base64"));
}
#[test]
fn input_file_block_with_file_data_surfaces_media_type_not_base64() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"input_file\",",
"\"file_data\":\"data:application/pdf;base64,JVBERi_NOISE\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] [input_file:application/pdf]");
assert!(!chunks[0].text.contains("JVBERi_NOISE"));
}
#[test]
fn input_file_block_with_data_url_surfaces_media_type_not_base64() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"input_file\",",
"\"file_url\":\"data:application/pdf;base64,JVBERi_URL_NOISE\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] [input_file:application/pdf]");
assert!(!chunks[0].text.contains("JVBERi_URL_NOISE"));
}
#[test]
fn input_file_block_with_file_id_renders_with_file_prefix() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"input_file\",\"file_id\":\"file_abc123\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] [input_file:file] file_abc123");
}
#[test]
fn input_file_block_file_url_wins_over_filename_and_file_id() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"input_file\",",
"\"file_url\":\"https://example.com/r.pdf\",",
"\"filename\":\"r.pdf\",\"file_id\":\"file_abc\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[user] [input_file] https://example.com/r.pdf"
);
assert!(!chunks[0].text.contains("file_abc"));
}
#[test]
fn input_file_block_filename_wins_over_file_id() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"input_file\",",
"\"filename\":\"notes.pdf\",\"file_id\":\"file_xyz\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] [input_file] notes.pdf");
assert!(!chunks[0].text.contains("file_xyz"));
}
#[test]
fn input_file_block_with_no_anchors_drops() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"input_file\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert!(
chunks.is_empty(),
"input_file block with no anchors should drop"
);
}
#[test]
fn input_file_block_with_malformed_data_url_falls_through_to_file_id() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"input_file\",",
"\"file_url\":\"data:GARBAGENOSEMI\",\"file_id\":\"file_fallback\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] [input_file:file] file_fallback");
assert!(!chunks[0].text.contains("GARBAGENOSEMI"));
}
#[test]
fn input_file_block_text_field_wins_over_input_file_prefix() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"input_file\",\"text\":\"see attached report\",",
"\"file_url\":\"https://example.com/r.pdf\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] see attached report");
}
#[test]
fn input_file_block_interleaves_with_text_in_join_order() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"input_text\",\"text\":\"summarize this file\"},",
"{\"type\":\"input_file\",",
"\"file_url\":\"https://example.com/q3.pdf\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[user] summarize this file\n[input_file] https://example.com/q3.pdf"
);
}
#[test]
fn non_input_file_block_with_file_url_field_keeps_no_input_file_prefix() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"text\",\"text\":\"plain text\",",
"\"file_url\":\"https://example.com/x.pdf\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] plain text");
}
#[test]
fn input_file_block_does_not_collide_with_anthropic_document_block() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"document\",\"source\":{\"type\":\"url\",",
"\"url\":\"https://example.com/anthropic.pdf\"}},",
"{\"type\":\"input_file\",\"file_url\":\"https://example.com/openai.pdf\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[user] [document] https://example.com/anthropic.pdf\n[input_file] https://example.com/openai.pdf"
);
}
#[test]
fn input_audio_block_with_transcript_renders_transcript_anchor() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"input_audio\",",
"\"input_audio\":{\"data\":\"BASE64AUDIOBLOB_NEVER_INDEX_ME\",\"format\":\"mp3\"},",
"\"transcript\":\"hello transcript\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] [input_audio] hello transcript");
assert!(!chunks[0].text.contains("BASE64AUDIOBLOB_NEVER_INDEX_ME"));
}
#[test]
fn input_audio_block_with_file_id_renders_with_file_prefix() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"input_audio\",\"file_id\":\"file_audio_abc123\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[user] [input_audio:file] file_audio_abc123"
);
}
#[test]
fn input_audio_block_with_only_format_renders_format_anchor() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"input_audio\",",
"\"input_audio\":{\"data\":\"BASE64AUDIOBLOB_NEVER_INDEX_ME\",\"format\":\"wav\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] [input_audio:wav]");
assert!(!chunks[0].text.contains("BASE64AUDIOBLOB_NEVER_INDEX_ME"));
}
#[test]
fn input_audio_block_transcript_wins_over_file_id_and_format() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"input_audio\",",
"\"input_audio\":{\"data\":\"AAAA\",\"format\":\"wav\"},",
"\"file_id\":\"file_audio_xyz\",",
"\"transcript\":\"the winning transcript\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[user] [input_audio] the winning transcript"
);
assert!(!chunks[0].text.contains("file_audio_xyz"));
assert!(!chunks[0].text.contains("wav"));
}
#[test]
fn input_audio_block_file_id_wins_over_format() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"input_audio\",",
"\"input_audio\":{\"data\":\"AAAA\",\"format\":\"wav\"},",
"\"file_id\":\"file_audio_only\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] [input_audio:file] file_audio_only");
assert!(!chunks[0].text.contains("wav"));
}
#[test]
fn input_audio_block_with_no_anchors_drops() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"input_audio\",",
"\"input_audio\":{\"data\":\"BASE64AUDIOBLOB_NEVER_INDEX_ME\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert!(
chunks.is_empty(),
"input_audio block with no anchors should drop"
);
}
#[test]
fn input_audio_block_text_field_wins_over_input_audio_prefix() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"input_audio\",\"text\":\"caption: a greeting\",",
"\"transcript\":\"hello transcript\",",
"\"input_audio\":{\"data\":\"AAAA\",\"format\":\"wav\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] caption: a greeting");
}
#[test]
fn input_audio_block_interleaves_with_text_in_join_order() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"input_text\",\"text\":\"transcribe this\"},",
"{\"type\":\"input_audio\",",
"\"input_audio\":{\"data\":\"AAAA\",\"format\":\"wav\"},",
"\"transcript\":\"hello world\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[user] transcribe this\n[input_audio] hello world"
);
}
#[test]
fn input_audio_block_never_leaks_nested_data_base64() {
let cases = [
concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"input_audio\",",
"\"input_audio\":{\"data\":\"LEAKCANARY_TRANSCRIPT\",\"format\":\"wav\"},",
"\"transcript\":\"hi\"}",
"]}\n"
),
concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"input_audio\",",
"\"input_audio\":{\"data\":\"LEAKCANARY_FILEID\",\"format\":\"mp3\"},",
"\"file_id\":\"file_x\"}",
"]}\n"
),
concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"input_audio\",",
"\"input_audio\":{\"data\":\"LEAKCANARY_FORMAT\",\"format\":\"wav\"}}",
"]}\n"
),
];
for jsonl in cases {
for chunk in extract_jsonl(jsonl) {
assert!(
!chunk.text.contains("LEAKCANARY"),
"nested input_audio.data must never appear in chunk text; got: {}",
chunk.text
);
}
}
}
#[test]
fn non_input_audio_block_with_transcript_field_keeps_no_input_audio_prefix() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"text\",\"text\":\"plain text\",",
"\"transcript\":\"stray transcript field\",",
"\"file_id\":\"stray_file_id\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] plain text");
assert!(!chunks[0].text.contains("input_audio"));
}
#[test]
fn input_audio_block_mixed_with_image_and_file_preserves_array_order() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"input_image\",\"image_url\":\"https://example.com/a.png\"},",
"{\"type\":\"input_audio\",",
"\"input_audio\":{\"data\":\"AAAA\",\"format\":\"wav\"},",
"\"transcript\":\"hi there\"},",
"{\"type\":\"input_file\",\"file_url\":\"https://example.com/b.pdf\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[user] [input_image] https://example.com/a.png\n[input_audio] hi there\n[input_file] https://example.com/b.pdf"
);
}
#[test]
fn output_audio_block_with_transcript_renders_transcript_anchor() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"output_audio\",",
"\"data\":\"BASE64OUTAUDIO_NEVER_INDEX_ME\",\"format\":\"wav\",",
"\"transcript\":\"synthesized greeting\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [output_audio] synthesized greeting"
);
assert!(!chunks[0].text.contains("BASE64OUTAUDIO_NEVER_INDEX_ME"));
}
#[test]
fn output_audio_block_with_file_id_renders_with_file_prefix() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"output_audio\",\"file_id\":\"file_out_audio_abc123\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [output_audio:file] file_out_audio_abc123"
);
}
#[test]
fn output_audio_block_with_flat_format_renders_format_anchor() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"output_audio\",",
"\"data\":\"BASE64OUTAUDIO_NEVER_INDEX_ME\",\"format\":\"pcm16\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] [output_audio:pcm16]");
assert!(!chunks[0].text.contains("BASE64OUTAUDIO_NEVER_INDEX_ME"));
}
#[test]
fn output_audio_block_with_nested_format_renders_format_anchor() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"output_audio\",",
"\"output_audio\":{\"data\":\"BASE64OUTAUDIO_NEVER_INDEX_ME\",\"format\":\"wav\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] [output_audio:wav]");
assert!(!chunks[0].text.contains("BASE64OUTAUDIO_NEVER_INDEX_ME"));
}
#[test]
fn output_audio_block_transcript_wins_over_file_id_and_format() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"output_audio\",",
"\"output_audio\":{\"data\":\"AAAA\",\"format\":\"wav\"},",
"\"format\":\"pcm16\",",
"\"file_id\":\"file_out_audio_xyz\",",
"\"transcript\":\"the winning transcript\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [output_audio] the winning transcript"
);
assert!(!chunks[0].text.contains("file_out_audio_xyz"));
assert!(!chunks[0].text.contains("pcm16"));
assert!(!chunks[0].text.contains("wav"));
}
#[test]
fn output_audio_block_file_id_wins_over_format() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"output_audio\",",
"\"output_audio\":{\"data\":\"AAAA\",\"format\":\"wav\"},",
"\"format\":\"pcm16\",",
"\"file_id\":\"file_out_only\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [output_audio:file] file_out_only"
);
assert!(!chunks[0].text.contains("pcm16"));
assert!(!chunks[0].text.contains("wav"));
}
#[test]
fn output_audio_block_flat_format_wins_over_nested_format() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"output_audio\",",
"\"output_audio\":{\"data\":\"AAAA\",\"format\":\"mp3\"},",
"\"format\":\"pcm16\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] [output_audio:pcm16]");
assert!(!chunks[0].text.contains("mp3"));
}
#[test]
fn output_audio_block_with_no_anchors_drops() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"output_audio\",",
"\"data\":\"BASE64OUTAUDIO_NEVER_INDEX_ME\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert!(
chunks.is_empty(),
"output_audio block with no anchors should drop"
);
}
#[test]
fn output_audio_block_text_field_wins_over_output_audio_prefix() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"output_audio\",\"text\":\"caption: a greeting\",",
"\"transcript\":\"synthesized greeting\",",
"\"data\":\"AAAA\",\"format\":\"wav\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] caption: a greeting");
}
#[test]
fn output_audio_block_interleaves_with_text_in_join_order() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"text\":\"here is your reply\"},",
"{\"type\":\"output_audio\",",
"\"data\":\"AAAA\",\"format\":\"wav\",",
"\"transcript\":\"hello world\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] here is your reply\n[output_audio] hello world"
);
}
#[test]
fn output_audio_block_never_leaks_data_base64() {
let cases = [
concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"output_audio\",",
"\"data\":\"LEAKCANARY_FLAT_TRANSCRIPT\",",
"\"output_audio\":{\"data\":\"LEAKCANARY_NEST_TRANSCRIPT\",\"format\":\"wav\"},",
"\"transcript\":\"hi\"}",
"]}\n"
),
concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"output_audio\",",
"\"data\":\"LEAKCANARY_FLAT_FILEID\",",
"\"file_id\":\"file_x\"}",
"]}\n"
),
concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"output_audio\",",
"\"data\":\"LEAKCANARY_FLAT_FORMAT\",\"format\":\"wav\"}",
"]}\n"
),
concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"output_audio\",",
"\"output_audio\":{\"data\":\"LEAKCANARY_NEST_FORMAT\",\"format\":\"wav\"}}",
"]}\n"
),
];
for jsonl in cases {
for chunk in extract_jsonl(jsonl) {
assert!(
!chunk.text.contains("LEAKCANARY"),
"output_audio data must never appear in chunk text; got: {}",
chunk.text
);
}
}
}
#[test]
fn non_output_audio_block_with_transcript_field_keeps_no_output_audio_prefix() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"text\":\"plain reply\",",
"\"transcript\":\"stray transcript field\",",
"\"file_id\":\"stray_file_id\",",
"\"format\":\"wav\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] plain reply");
assert!(!chunks[0].text.contains("output_audio"));
}
#[test]
fn output_audio_block_does_not_match_input_audio_extractor() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"input_audio\",\"transcript\":\"user said hi\"}",
"]}\n",
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"output_audio\",\"transcript\":\"assistant said hi back\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 2);
assert_eq!(chunks[0].text, "[user] [input_audio] user said hi");
assert_eq!(
chunks[1].text,
"[assistant] [output_audio] assistant said hi back"
);
}
#[test]
fn document_block_with_url_source_renders_with_document_prefix_and_url() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"document\",\"source\":{\"type\":\"url\",",
"\"url\":\"https://example.com/paper.pdf\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[user] [document] https://example.com/paper.pdf"
);
}
#[test]
fn document_block_with_base64_source_renders_with_media_type() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"document\",\"source\":{\"type\":\"base64\",",
"\"media_type\":\"application/pdf\",\"data\":\"JVBERi0xLjQK\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] [document:application/pdf]");
assert!(!chunks[0].text.contains("JVBERi"));
}
#[test]
fn document_block_with_text_source_inlines_data() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"document\",\"source\":{\"type\":\"text\",",
"\"media_type\":\"text/plain\",\"data\":\"Quarterly report: revenue up 12%.\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[user] [document] Quarterly report: revenue up 12%."
);
}
#[test]
fn document_block_with_content_source_recurses_into_nested_blocks() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"document\",\"source\":{\"type\":\"content\",",
"\"content\":[",
"{\"type\":\"text\",\"text\":\"section one\"},",
"{\"type\":\"text\",\"text\":\"section two\"}",
"]}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] [document] section one\nsection two");
}
#[test]
fn document_block_url_wins_over_media_type() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"document\",\"source\":{\"type\":\"url\",",
"\"url\":\"https://example.com/spec.pdf\",\"media_type\":\"application/pdf\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[user] [document] https://example.com/spec.pdf"
);
}
#[test]
fn document_block_with_no_anchor_drops() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"document\",\"source\":{\"type\":\"base64\",\"data\":\"AAAA\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert!(
chunks.is_empty(),
"document block with no usable anchor should drop"
);
}
#[test]
fn document_block_with_missing_source_drops() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"document\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert!(
chunks.is_empty(),
"document block with no source should drop"
);
}
#[test]
fn document_block_text_field_wins_over_document_prefix() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"document\",\"text\":\"caption: financial report\",",
"\"source\":{\"type\":\"url\",\"url\":\"https://example.com/q4.pdf\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] caption: financial report");
}
#[test]
fn document_block_interleaves_with_text_in_join_order() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"text\",\"text\":\"please summarize\"},",
"{\"type\":\"document\",\"source\":{\"type\":\"url\",",
"\"url\":\"https://example.com/whitepaper.pdf\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[user] please summarize\n[document] https://example.com/whitepaper.pdf"
);
}
#[test]
fn non_document_block_with_source_field_keeps_no_document_prefix() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"text\",\"text\":\"plain text\",",
"\"source\":{\"type\":\"url\",\"url\":\"https://example.com/x.pdf\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] plain text");
}
#[test]
fn document_block_with_blank_url_falls_through_to_media_type() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"document\",\"source\":{\"type\":\"base64\",",
"\"url\":\" \",\"media_type\":\"application/pdf\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] [document:application/pdf]");
}
#[test]
fn document_block_text_source_with_blank_data_falls_through() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"document\",\"source\":{\"type\":\"text\",",
"\"data\":\" \"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert!(
chunks.is_empty(),
"text-source document with blank data and no fallback anchor should drop"
);
}
#[test]
fn document_block_text_source_blank_data_falls_through_to_media_type() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"document\",\"source\":{\"type\":\"text\",",
"\"data\":\"\",\"media_type\":\"text/plain\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] [document:text/plain]");
}
#[test]
fn function_call_block_with_string_arguments_passes_through_unparsed() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"function_call\",\"call_id\":\"call_123\",\"name\":\"docs_search\",",
"\"arguments\":\"{\\\"q\\\":\\\"hello\\\"}\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [tool_use:docs_search] {\"q\":\"hello\"}"
);
assert_eq!(chunks[0].tool_name.as_deref(), Some("docs_search"));
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_123"));
}
#[test]
fn function_call_block_structured_arguments_object_serialized_in_sorted_order() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"function_call\",\"call_id\":\"call_obj\",\"name\":\"search\",",
"\"arguments\":{\"zeta\":1,\"alpha\":2}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [tool_use:search] {\"alpha\":2,\"zeta\":1}"
);
}
#[test]
fn function_call_block_with_missing_arguments_keeps_prefix() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"function_call\",\"call_id\":\"call_p\",\"name\":\"ping\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] [tool_use:ping]");
assert_eq!(chunks[0].tool_name.as_deref(), Some("ping"));
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_p"));
}
#[test]
fn function_call_block_with_empty_arguments_string_keeps_prefix() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"function_call\",\"call_id\":\"call_e\",\"name\":\"ping\",",
"\"arguments\":\"{}\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] [tool_use:ping] {}");
}
#[test]
fn function_call_block_with_empty_arguments_object_keeps_prefix() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"function_call\",\"call_id\":\"call_e2\",\"name\":\"ping\",",
"\"arguments\":{}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] [tool_use:ping]");
}
#[test]
fn function_call_block_without_name_drops() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"function_call\",\"call_id\":\"call_x\",",
"\"arguments\":\"{}\"}",
"]}\n"
);
assert!(extract_jsonl(jsonl).is_empty());
}
#[test]
fn function_call_block_with_blank_name_drops() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"function_call\",\"call_id\":\"call_x\",\"name\":\" \",",
"\"arguments\":\"{}\"}",
"]}\n"
);
assert!(extract_jsonl(jsonl).is_empty());
}
#[test]
fn function_call_block_with_text_field_still_prefers_text() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"function_call\",\"call_id\":\"call_t\",\"name\":\"search\",",
"\"text\":\"direct text wins\",\"arguments\":\"{\\\"q\\\":\\\"ignored\\\"}\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] direct text wins");
}
#[test]
fn text_and_function_call_blocks_interleave_in_join_order() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"text\":\"let me search\"},",
"{\"type\":\"function_call\",\"call_id\":\"call_1\",\"name\":\"docs_search\",",
"\"arguments\":\"{\\\"q\\\":\\\"hello\\\"}\"},",
"{\"type\":\"text\",\"text\":\"done\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] let me search\n[tool_use:docs_search] {\"q\":\"hello\"}\ndone"
);
}
#[test]
fn outer_tool_name_wins_over_nested_function_call_block() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"tool_name\":\"outer-tool\",\"content\":[",
"{\"type\":\"function_call\",\"call_id\":\"call_x\",\"name\":\"inner-tool\",",
"\"arguments\":\"{}\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_name.as_deref(), Some("outer-tool"));
}
#[test]
fn outer_tool_call_id_wins_over_nested_function_call_block() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"tool_call_id\":\"outer-call\",\"content\":[",
"{\"type\":\"function_call\",\"call_id\":\"inner-call\",\"name\":\"search\",",
"\"arguments\":\"{}\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("outer-call"));
}
#[test]
fn inner_message_envelope_function_call_block_recovers_metadata() {
let jsonl = concat!(
"{\"type\":\"assistant\",\"sessionId\":\"sess-openai\",",
"\"message\":{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"function_call\",\"call_id\":\"call_inner\",\"name\":\"search\",",
"\"arguments\":\"{\\\"q\\\":\\\"hi\\\"}\"}",
"]}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [tool_use:search] {\"q\":\"hi\"}"
);
assert_eq!(chunks[0].session_id.as_deref(), Some("sess-openai"));
assert_eq!(chunks[0].tool_name.as_deref(), Some("search"));
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_inner"));
}
#[test]
fn function_call_block_tool_call_id_accepts_alias_set() {
for alias in [
"tool_call_id",
"toolCallId",
"tool_use_id",
"toolUseId",
"call_id",
"callId",
] {
let jsonl = format!(
concat!(
"{{\"role\":\"assistant\",\"content\":[",
"{{\"type\":\"function_call\",\"{alias}\":\"call_alias\",",
"\"name\":\"search\",\"arguments\":\"{{}}\"}}",
"]}}\n"
),
alias = alias
);
let chunks = extract_jsonl(&jsonl);
assert_eq!(chunks.len(), 1, "alias {alias} should produce a chunk");
assert_eq!(
chunks[0].tool_call_id.as_deref(),
Some("call_alias"),
"alias {alias} did not populate tool_call_id"
);
}
}
#[test]
fn function_call_block_id_alias_not_recognised_for_tool_call_id() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"function_call\",\"id\":\"fc_should_not_match\",\"name\":\"search\",",
"\"arguments\":\"{}\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_call_id, None);
assert_eq!(chunks[0].tool_name.as_deref(), Some("search"));
}
#[test]
fn function_call_recovery_only_uses_first_usable_block() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"function_call\",\"call_id\":\"call_first\",\"name\":\"first\",",
"\"arguments\":\"{}\"},",
"{\"type\":\"function_call\",\"call_id\":\"call_second\",\"name\":\"second\",",
"\"arguments\":\"{\\\"q\\\":\\\"x\\\"}\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [tool_use:first] {}\n[tool_use:second] {\"q\":\"x\"}"
);
assert_eq!(chunks[0].tool_name.as_deref(), Some("first"));
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_first"));
}
#[test]
fn non_function_call_typed_block_with_call_id_does_not_populate_tool_call_id() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"call_id\":\"call_should_not_match\",",
"\"text\":\"hi\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_call_id, None);
}
#[test]
fn function_call_output_block_with_string_output_renders_tool_result_prefix() {
let jsonl = concat!(
"{\"role\":\"tool\",\"content\":[",
"{\"type\":\"function_call_output\",\"call_id\":\"call_123\",",
"\"output\":\"the doc says provenance is local-first\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[tool] [tool_result] the doc says provenance is local-first"
);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_123"));
assert_eq!(chunks[0].tool_name, None);
}
#[test]
fn function_call_output_block_with_number_and_bool_outputs_pass_through() {
let num_jsonl = concat!(
"{\"role\":\"tool\",\"content\":[",
"{\"type\":\"function_call_output\",\"call_id\":\"call_n\",",
"\"output\":42}",
"]}\n"
);
let chunks = extract_jsonl(num_jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[tool] [tool_result] 42");
let bool_jsonl = concat!(
"{\"role\":\"tool\",\"content\":[",
"{\"type\":\"function_call_output\",\"call_id\":\"call_b\",",
"\"output\":true}",
"]}\n"
);
let chunks = extract_jsonl(bool_jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[tool] [tool_result] true");
}
#[test]
fn function_call_output_block_structured_object_serialized_in_sorted_order() {
let jsonl = concat!(
"{\"role\":\"tool\",\"content\":[",
"{\"type\":\"function_call_output\",\"call_id\":\"call_obj\",",
"\"output\":{\"zeta\":1,\"alpha\":2}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[tool] [tool_result] {\"alpha\":2,\"zeta\":1}"
);
}
#[test]
fn function_call_output_block_structured_array_serialized_compactly() {
let jsonl = concat!(
"{\"role\":\"tool\",\"content\":[",
"{\"type\":\"function_call_output\",\"call_id\":\"call_arr\",",
"\"output\":[\"a\",\"b\",1]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[tool] [tool_result] [\"a\",\"b\",1]");
}
#[test]
fn function_call_output_block_with_missing_output_drops() {
let jsonl = concat!(
"{\"role\":\"tool\",\"content\":[",
"{\"type\":\"function_call_output\",\"call_id\":\"call_p\"}",
"]}\n"
);
assert!(extract_jsonl(jsonl).is_empty());
}
#[test]
fn function_call_output_block_with_empty_object_output_drops() {
let jsonl = concat!(
"{\"role\":\"tool\",\"content\":[",
"{\"type\":\"function_call_output\",\"call_id\":\"call_e\",",
"\"output\":{}}",
"]}\n"
);
assert!(extract_jsonl(jsonl).is_empty());
}
#[test]
fn function_call_output_block_with_empty_array_output_drops() {
let jsonl = concat!(
"{\"role\":\"tool\",\"content\":[",
"{\"type\":\"function_call_output\",\"call_id\":\"call_e2\",",
"\"output\":[]}",
"]}\n"
);
assert!(extract_jsonl(jsonl).is_empty());
}
#[test]
fn function_call_output_block_with_blank_string_output_drops() {
let jsonl = concat!(
"{\"role\":\"tool\",\"content\":[",
"{\"type\":\"function_call_output\",\"call_id\":\"call_blank\",",
"\"output\":\" \"}",
"]}\n"
);
assert!(extract_jsonl(jsonl).is_empty());
}
#[test]
fn function_call_output_block_with_text_field_still_prefers_text() {
let jsonl = concat!(
"{\"role\":\"tool\",\"content\":[",
"{\"type\":\"function_call_output\",\"call_id\":\"call_t\",",
"\"text\":\"direct text wins\",\"output\":\"ignored payload\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[tool] direct text wins");
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_t"));
}
#[test]
fn text_function_call_and_function_call_output_blocks_interleave_in_join_order() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"text\":\"let me search\"},",
"{\"type\":\"function_call\",\"call_id\":\"call_1\",\"name\":\"docs_search\",",
"\"arguments\":\"{\\\"q\\\":\\\"hello\\\"}\"},",
"{\"type\":\"function_call_output\",\"call_id\":\"call_1\",",
"\"output\":\"found three matches\"},",
"{\"type\":\"text\",\"text\":\"done\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
concat!(
"[assistant] let me search\n",
"[tool_use:docs_search] {\"q\":\"hello\"}\n",
"[tool_result] found three matches\n",
"done"
)
);
assert_eq!(chunks[0].tool_name.as_deref(), Some("docs_search"));
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_1"));
}
#[test]
fn function_call_output_block_alone_in_content_recovers_tool_call_id() {
let jsonl = concat!(
"{\"role\":\"tool\",\"content\":[",
"{\"type\":\"function_call_output\",\"call_id\":\"call_solo\",",
"\"output\":\"ok\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[tool] [tool_result] ok");
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_solo"));
}
#[test]
fn function_call_output_block_tool_call_id_accepts_alias_set() {
for alias in [
"tool_call_id",
"toolCallId",
"tool_use_id",
"toolUseId",
"call_id",
"callId",
] {
let jsonl = format!(
concat!(
"{{\"role\":\"tool\",\"content\":[",
"{{\"type\":\"function_call_output\",\"{alias}\":\"call_alias\",",
"\"output\":\"ok\"}}",
"]}}\n"
),
alias = alias
);
let chunks = extract_jsonl(&jsonl);
assert_eq!(chunks.len(), 1, "alias {alias} should produce a chunk");
assert_eq!(
chunks[0].tool_call_id.as_deref(),
Some("call_alias"),
"alias {alias} did not populate tool_call_id"
);
}
}
#[test]
fn function_call_output_block_id_alias_not_recognised_for_tool_call_id() {
let jsonl = concat!(
"{\"role\":\"tool\",\"content\":[",
"{\"type\":\"function_call_output\",\"id\":\"fco_should_not_match\",",
"\"output\":\"ok\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_call_id, None);
assert!(chunks[0].text.contains("[tool_result] ok"));
}
#[test]
fn outer_tool_call_id_wins_over_nested_function_call_output_block() {
let jsonl = concat!(
"{\"role\":\"tool\",\"tool_call_id\":\"outer-call\",\"content\":[",
"{\"type\":\"function_call_output\",\"call_id\":\"inner-call\",",
"\"output\":\"ok\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("outer-call"));
}
#[test]
fn inner_message_envelope_function_call_output_block_recovers_metadata() {
let jsonl = concat!(
"{\"type\":\"tool_result\",\"sessionId\":\"sess-openai\",",
"\"message\":{\"role\":\"tool\",\"content\":[",
"{\"type\":\"function_call_output\",\"call_id\":\"call_inner\",",
"\"output\":\"forty two\"}",
"]}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[tool] [tool_result] forty two");
assert_eq!(chunks[0].session_id.as_deref(), Some("sess-openai"));
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_inner"));
}
#[test]
fn function_call_output_block_does_not_contribute_tool_name() {
let jsonl = concat!(
"{\"role\":\"tool\",\"content\":[",
"{\"type\":\"function_call_output\",\"call_id\":\"call_x\",",
"\"name\":\"should_not_match\",\"output\":\"ok\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_name, None);
}
#[test]
fn non_function_call_output_typed_block_with_output_does_not_render_tool_result() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"output\":\"should not surface\",",
"\"text\":\"hi\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] hi");
assert!(!chunks[0].text.contains("[tool_result]"));
}
#[test]
fn mcp_tool_use_block_with_server_name_and_structured_input_is_extracted() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"mcp_tool_use\",\"id\":\"mcptoolu_01\",",
"\"server_name\":\"linear\",\"name\":\"create_issue\",",
"\"input\":{\"title\":\"bug\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [mcp_tool_use:linear/create_issue] {\"title\":\"bug\"}"
);
assert_eq!(chunks[0].tool_name.as_deref(), Some("create_issue"));
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("mcptoolu_01"));
}
#[test]
fn mcp_tool_use_block_structured_input_object_serialized_in_sorted_order() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"mcp_tool_use\",\"server_name\":\"db\",\"name\":\"query\",",
"\"input\":{\"zeta\":1,\"alpha\":2}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [mcp_tool_use:db/query] {\"alpha\":2,\"zeta\":1}"
);
}
#[test]
fn mcp_tool_use_block_with_string_input_passes_through() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"mcp_tool_use\",\"server_name\":\"echo\",\"name\":\"say\",",
"\"input\":\"hello world\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [mcp_tool_use:echo/say] hello world"
);
}
#[test]
fn mcp_tool_use_block_without_server_name_uses_name_only_prefix() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"mcp_tool_use\",\"id\":\"mcptoolu_02\",",
"\"name\":\"detached_call\",\"input\":{\"q\":\"x\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [mcp_tool_use:detached_call] {\"q\":\"x\"}"
);
}
#[test]
fn mcp_tool_use_block_blank_server_name_falls_back_to_name_only_prefix() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"mcp_tool_use\",\"server_name\":\" \",",
"\"name\":\"do_thing\",\"input\":{}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] [mcp_tool_use:do_thing]");
}
#[test]
fn mcp_tool_use_block_with_missing_input_keeps_prefix() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"mcp_tool_use\",\"server_name\":\"linear\",\"name\":\"ping\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] [mcp_tool_use:linear/ping]");
}
#[test]
fn mcp_tool_use_block_with_empty_input_object_keeps_prefix() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"mcp_tool_use\",\"server_name\":\"linear\",\"name\":\"noop\",",
"\"input\":{}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] [mcp_tool_use:linear/noop]");
}
#[test]
fn mcp_tool_use_block_missing_name_drops() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"mcp_tool_use\",\"server_name\":\"linear\",",
"\"input\":{\"q\":\"x\"}}",
"]}\n"
);
assert!(extract_jsonl(jsonl).is_empty());
}
#[test]
fn mcp_tool_use_block_text_field_still_wins() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"mcp_tool_use\",\"server_name\":\"linear\",\"name\":\"ignored\",",
"\"text\":\"direct text wins\",\"input\":{\"q\":\"x\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] direct text wins");
}
#[test]
fn mcp_tool_use_block_interleaves_with_other_blocks_in_join_order() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"text\":\"prelude\"},",
"{\"type\":\"mcp_tool_use\",\"server_name\":\"linear\",\"name\":\"create\",",
"\"input\":{\"q\":\"x\"}},",
"{\"type\":\"text\",\"text\":\"trailing\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] prelude\n[mcp_tool_use:linear/create] {\"q\":\"x\"}\ntrailing"
);
}
#[test]
fn non_mcp_tool_use_typed_block_with_server_name_does_not_trigger_prefix() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"server_name\":\"linear\",\"name\":\"ignored\",",
"\"text\":\"plain text\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] plain text");
assert!(!chunks[0].text.contains("[mcp_tool_use"));
}
#[test]
fn mcp_tool_use_block_id_recovers_tool_call_id_when_outer_missing() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"mcp_tool_use\",\"id\":\"mcptoolu_nested\",",
"\"server_name\":\"db\",\"name\":\"query\",\"input\":{}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("mcptoolu_nested"));
assert_eq!(chunks[0].tool_name.as_deref(), Some("query"));
}
#[test]
fn outer_tool_name_wins_over_nested_mcp_tool_use_block() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"tool_name\":\"outer-name\",\"content\":[",
"{\"type\":\"mcp_tool_use\",\"server_name\":\"db\",\"name\":\"inner-name\",",
"\"input\":{}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_name.as_deref(), Some("outer-name"));
}
#[test]
fn outer_tool_call_id_wins_over_nested_mcp_tool_use_block() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"tool_call_id\":\"outer-call\",\"content\":[",
"{\"type\":\"mcp_tool_use\",\"id\":\"mcptoolu_inner\",",
"\"server_name\":\"db\",\"name\":\"query\",\"input\":{}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("outer-call"));
}
#[test]
fn inner_message_envelope_mcp_tool_use_block_recovers_metadata() {
let jsonl = concat!(
"{\"type\":\"assistant\",\"sessionId\":\"sess-mcp\",",
"\"message\":{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"mcp_tool_use\",\"id\":\"mcptoolu_inner\",",
"\"server_name\":\"linear\",\"name\":\"create_issue\",",
"\"input\":{\"title\":\"bug\"}}",
"]}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [mcp_tool_use:linear/create_issue] {\"title\":\"bug\"}"
);
assert_eq!(chunks[0].tool_name.as_deref(), Some("create_issue"));
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("mcptoolu_inner"));
assert_eq!(chunks[0].session_id.as_deref(), Some("sess-mcp"));
}
#[test]
fn mcp_tool_result_block_renders_behind_distinct_prefix() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"mcp_tool_result\",\"tool_use_id\":\"mcptoolu_01\",",
"\"content\":[{\"type\":\"text\",\"text\":\"ticket LIN-42 created\"}]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[user] [mcp_tool_result] ticket LIN-42 created"
);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("mcptoolu_01"));
}
#[test]
fn mcp_tool_result_block_with_string_content_renders_inline() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"mcp_tool_result\",\"tool_use_id\":\"mcptoolu_02\",",
"\"content\":\"plain string reply\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[user] [mcp_tool_result] plain string reply"
);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("mcptoolu_02"));
}
#[test]
fn mcp_tool_result_error_block_renders_behind_error_prefix() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"mcp_tool_result\",\"tool_use_id\":\"mcptoolu_03\",",
"\"is_error\":true,\"content\":\"permission denied\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] [mcp_tool_error] permission denied");
assert!(
!chunks[0].text.contains("[tool_error]"),
"MCP error must not collide with the regular `[tool_error]` prefix"
);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("mcptoolu_03"));
}
#[test]
fn mcp_tool_result_block_with_is_error_false_keeps_success_prefix() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"mcp_tool_result\",\"tool_use_id\":\"mcptoolu_04\",",
"\"is_error\":false,\"content\":\"ok\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] [mcp_tool_result] ok");
}
#[test]
fn mcp_tool_result_block_with_empty_content_drops() {
let jsonl_empty_array = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"mcp_tool_result\",\"content\":[]}",
"]}\n"
);
assert!(extract_jsonl(jsonl_empty_array).is_empty());
let jsonl_missing_content = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"mcp_tool_result\",\"tool_use_id\":\"mcptoolu_05\"}",
"]}\n"
);
assert!(extract_jsonl(jsonl_missing_content).is_empty());
}
#[test]
fn mcp_tool_result_block_text_field_still_wins() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"mcp_tool_result\",\"text\":\"direct text wins\",",
"\"content\":\"ignored\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] direct text wins");
}
#[test]
fn mcp_tool_result_block_interleaves_with_other_blocks_in_join_order() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"text\",\"text\":\"prelude\"},",
"{\"type\":\"mcp_tool_result\",\"tool_use_id\":\"mcptoolu_06\",",
"\"content\":\"ticket created\"},",
"{\"type\":\"text\",\"text\":\"trailing note\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[user] prelude\n[mcp_tool_result] ticket created\ntrailing note"
);
}
#[test]
fn non_mcp_tool_result_typed_block_does_not_trigger_mcp_prefix() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"tool_result\",\"tool_use_id\":\"toolu_99\",",
"\"content\":\"regular result\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] regular result");
assert!(
!chunks[0].text.contains("[mcp_tool_result]"),
"regular tool_result must not get the MCP-only prefix"
);
}
#[test]
fn mcp_tool_result_block_id_recovers_tool_call_id_when_outer_missing() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"mcp_tool_result\",\"tool_use_id\":\"mcptoolu_recovered\",",
"\"content\":\"ok\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].tool_call_id.as_deref(),
Some("mcptoolu_recovered")
);
}
#[test]
fn mcp_tool_result_block_does_not_widen_to_top_level_id() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"mcp_tool_result\",\"id\":\"not-a-call-id\",",
"\"content\":\"ok\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert!(chunks[0].tool_call_id.is_none());
}
#[test]
fn outer_tool_call_id_wins_over_nested_mcp_tool_result_block() {
let jsonl = concat!(
"{\"role\":\"user\",\"tool_call_id\":\"outer-call\",\"content\":[",
"{\"type\":\"mcp_tool_result\",\"tool_use_id\":\"mcptoolu_inner\",",
"\"content\":\"ok\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("outer-call"));
}
#[test]
fn web_search_tool_result_block_renders_title_and_url_behind_distinct_prefix() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"web_search_tool_result\",\"tool_use_id\":\"srvtoolu_ws_01\",",
"\"content\":[",
"{\"type\":\"web_search_result\",\"url\":\"https://example.com/lantern\",",
"\"title\":\"Lantern docs\",\"encrypted_content\":\"OPAQUE_BLOB_X\",",
"\"page_age\":\"Jan 1, 2024\"}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [web_search_tool_result] Lantern docs https://example.com/lantern"
);
assert!(!chunks[0].text.contains("OPAQUE_BLOB_X"));
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("srvtoolu_ws_01"));
}
#[test]
fn web_search_tool_result_block_joins_multiple_results_in_order() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"web_search_tool_result\",\"tool_use_id\":\"srvtoolu_ws_02\",",
"\"content\":[",
"{\"type\":\"web_search_result\",\"url\":\"https://a.example/1\",\"title\":\"First\"},",
"{\"type\":\"web_search_result\",\"url\":\"https://b.example/2\",\"title\":\"Second\"}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [web_search_tool_result] First https://a.example/1\n\
[web_search_tool_result] Second https://b.example/2"
);
}
#[test]
fn web_search_tool_result_block_handles_title_only_and_url_only_entries() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"web_search_tool_result\",\"tool_use_id\":\"srvtoolu_ws_03\",",
"\"content\":[",
"{\"type\":\"web_search_result\",\"title\":\"Only Title\"},",
"{\"type\":\"web_search_result\",\"url\":\"https://only.url/\"},",
"{\"type\":\"web_search_result\",\"encrypted_content\":\"BLOB\"}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [web_search_tool_result] Only Title\n\
[web_search_tool_result] https://only.url/"
);
}
#[test]
fn web_search_tool_result_block_error_renders_behind_error_prefix() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"web_search_tool_result\",\"tool_use_id\":\"srvtoolu_ws_04\",",
"\"content\":{\"type\":\"web_search_tool_result_error\",",
"\"error_code\":\"max_uses_exceeded\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [web_search_tool_error] error_code=max_uses_exceeded"
);
assert!(!chunks[0].text.contains("[tool_error]"));
assert!(!chunks[0].text.contains("[mcp_tool_error]"));
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("srvtoolu_ws_04"));
}
#[test]
fn web_search_tool_result_block_with_empty_or_unusable_content_drops() {
let empty_array = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"web_search_tool_result\",\"tool_use_id\":\"srvtoolu_ws_05\",",
"\"content\":[]}",
"]}\n"
);
assert!(extract_jsonl(empty_array).is_empty());
let unusable_entries = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"web_search_tool_result\",\"tool_use_id\":\"srvtoolu_ws_06\",",
"\"content\":[",
"{\"type\":\"web_search_result\",\"encrypted_content\":\"OPAQUE\"}",
"]}",
"]}\n"
);
assert!(extract_jsonl(unusable_entries).is_empty());
let error_no_code = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"web_search_tool_result\",\"tool_use_id\":\"srvtoolu_ws_07\",",
"\"content\":{\"type\":\"web_search_tool_result_error\"}}",
"]}\n"
);
assert!(extract_jsonl(error_no_code).is_empty());
let missing_content = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"web_search_tool_result\",\"tool_use_id\":\"srvtoolu_ws_08\"}",
"]}\n"
);
assert!(extract_jsonl(missing_content).is_empty());
}
#[test]
fn web_search_tool_result_block_text_field_still_wins() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"web_search_tool_result\",\"text\":\"direct text wins\",",
"\"content\":[",
"{\"type\":\"web_search_result\",\"title\":\"ignored\",\"url\":\"https://ignored/\"}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] direct text wins");
}
#[test]
fn web_search_tool_result_block_interleaves_with_other_blocks_in_join_order() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"text\":\"searching the web\"},",
"{\"type\":\"web_search_tool_result\",\"tool_use_id\":\"srvtoolu_ws_09\",",
"\"content\":[",
"{\"type\":\"web_search_result\",\"title\":\"hit\",\"url\":\"https://h/\"}",
"]},",
"{\"type\":\"text\",\"text\":\"done\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] searching the web\n\
[web_search_tool_result] hit https://h/\n\
done"
);
}
#[test]
fn non_web_search_typed_block_does_not_trigger_web_search_prefix() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"text\":\"plain prose\",\"content\":[",
"{\"type\":\"web_search_result\",\"title\":\"should not surface\",\"url\":\"https://nope/\"}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] plain prose");
assert!(!chunks[0].text.contains("[web_search_tool_result]"));
}
#[test]
fn web_search_tool_result_block_recovers_tool_call_id_when_outer_missing() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"web_search_tool_result\",\"tool_use_id\":\"srvtoolu_recovered\",",
"\"content\":[",
"{\"type\":\"web_search_result\",\"title\":\"t\",\"url\":\"https://u/\"}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].tool_call_id.as_deref(),
Some("srvtoolu_recovered")
);
}
#[test]
fn web_search_tool_result_block_does_not_widen_to_top_level_id() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"web_search_tool_result\",\"id\":\"not-a-call-id\",",
"\"content\":[",
"{\"type\":\"web_search_result\",\"title\":\"t\",\"url\":\"https://u/\"}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert!(chunks[0].tool_call_id.is_none());
}
#[test]
fn outer_tool_call_id_wins_over_nested_web_search_tool_result_block() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"tool_call_id\":\"outer-call\",\"content\":[",
"{\"type\":\"web_search_tool_result\",\"tool_use_id\":\"srvtoolu_inner\",",
"\"content\":[",
"{\"type\":\"web_search_result\",\"title\":\"t\",\"url\":\"https://u/\"}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("outer-call"));
}
#[test]
fn web_fetch_tool_result_block_renders_url_behind_distinct_prefix() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"web_fetch_tool_result\",\"tool_use_id\":\"srvtoolu_wf_01\",",
"\"content\":{\"type\":\"web_fetch_result\",",
"\"url\":\"https://docs.lantern.example/intro\",",
"\"retrieved_at\":\"2026-01-01T00:00:00Z\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [web_fetch_tool_result] https://docs.lantern.example/intro"
);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("srvtoolu_wf_01"));
}
#[test]
fn web_fetch_tool_result_block_folds_in_nested_document_body() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"web_fetch_tool_result\",\"tool_use_id\":\"srvtoolu_wf_02\",",
"\"content\":{\"type\":\"web_fetch_result\",",
"\"url\":\"https://docs.lantern.example/intro\",",
"\"content\":{\"type\":\"document\",\"source\":{\"type\":\"text\",",
"\"media_type\":\"text/plain\",\"data\":\"lantern is a local memory engine\"}}}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [web_fetch_tool_result] https://docs.lantern.example/intro\n\
[document] lantern is a local memory engine"
);
}
#[test]
fn web_fetch_tool_result_block_omits_base64_payload_from_nested_document() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"web_fetch_tool_result\",\"tool_use_id\":\"srvtoolu_wf_03\",",
"\"content\":{\"type\":\"web_fetch_result\",",
"\"url\":\"https://docs.lantern.example/report.pdf\",",
"\"content\":{\"type\":\"document\",\"source\":{\"type\":\"base64\",",
"\"media_type\":\"application/pdf\",\"data\":\"OPAQUE_FETCH_BLOB\"}}}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [web_fetch_tool_result] https://docs.lantern.example/report.pdf\n\
[document:application/pdf]"
);
assert!(!chunks[0].text.contains("OPAQUE_FETCH_BLOB"));
}
#[test]
fn web_fetch_tool_result_block_error_renders_behind_distinct_error_prefix() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"web_fetch_tool_result\",\"tool_use_id\":\"srvtoolu_wf_04\",",
"\"content\":{\"type\":\"web_fetch_tool_result_error\",",
"\"error_code\":\"unsupported_content_type\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [web_fetch_tool_error] error_code=unsupported_content_type"
);
assert!(!chunks[0].text.contains("[tool_error]"));
assert!(!chunks[0].text.contains("[mcp_tool_error]"));
assert!(!chunks[0].text.contains("[web_search_tool_error]"));
assert!(!chunks[0].text.contains("[code_execution_error]"));
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("srvtoolu_wf_04"));
}
#[test]
fn web_fetch_tool_result_block_with_unusable_content_drops() {
let missing_url = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"web_fetch_tool_result\",\"tool_use_id\":\"srvtoolu_wf_05\",",
"\"content\":{\"type\":\"web_fetch_result\",\"retrieved_at\":\"x\"}}",
"]}\n"
);
assert!(extract_jsonl(missing_url).is_empty());
let blank_url = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"web_fetch_tool_result\",\"tool_use_id\":\"srvtoolu_wf_06\",",
"\"content\":{\"type\":\"web_fetch_result\",\"url\":\" \"}}",
"]}\n"
);
assert!(extract_jsonl(blank_url).is_empty());
let error_no_code = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"web_fetch_tool_result\",\"tool_use_id\":\"srvtoolu_wf_07\",",
"\"content\":{\"type\":\"web_fetch_tool_result_error\"}}",
"]}\n"
);
assert!(extract_jsonl(error_no_code).is_empty());
let unknown_inner_type = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"web_fetch_tool_result\",\"tool_use_id\":\"srvtoolu_wf_08\",",
"\"content\":{\"type\":\"some_future_shape\",\"url\":\"https://x/\"}}",
"]}\n"
);
assert!(extract_jsonl(unknown_inner_type).is_empty());
let missing_content = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"web_fetch_tool_result\",\"tool_use_id\":\"srvtoolu_wf_09\"}",
"]}\n"
);
assert!(extract_jsonl(missing_content).is_empty());
}
#[test]
fn web_fetch_tool_result_block_text_field_still_wins() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"web_fetch_tool_result\",\"text\":\"direct text wins\",",
"\"content\":{\"type\":\"web_fetch_result\",\"url\":\"https://ignored/\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] direct text wins");
}
#[test]
fn web_fetch_tool_result_block_interleaves_with_other_blocks_in_join_order() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"text\":\"fetching docs\"},",
"{\"type\":\"web_fetch_tool_result\",\"tool_use_id\":\"srvtoolu_wf_10\",",
"\"content\":{\"type\":\"web_fetch_result\",\"url\":\"https://h/\"}},",
"{\"type\":\"text\",\"text\":\"done\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] fetching docs\n\
[web_fetch_tool_result] https://h/\n\
done"
);
}
#[test]
fn non_web_fetch_typed_block_does_not_trigger_web_fetch_prefix() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"text\":\"plain prose\",\"content\":{",
"\"type\":\"web_fetch_result\",\"url\":\"https://nope/\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] plain prose");
assert!(!chunks[0].text.contains("[web_fetch_tool_result]"));
}
#[test]
fn web_fetch_tool_result_block_recovers_tool_call_id_when_outer_missing() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"web_fetch_tool_result\",\"tool_use_id\":\"srvtoolu_wf_recovered\",",
"\"content\":{\"type\":\"web_fetch_result\",\"url\":\"https://u/\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].tool_call_id.as_deref(),
Some("srvtoolu_wf_recovered")
);
}
#[test]
fn web_fetch_tool_result_block_does_not_widen_to_top_level_id() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"web_fetch_tool_result\",\"id\":\"not-a-call-id\",",
"\"content\":{\"type\":\"web_fetch_result\",\"url\":\"https://u/\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert!(chunks[0].tool_call_id.is_none());
}
#[test]
fn outer_tool_call_id_wins_over_nested_web_fetch_tool_result_block() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"tool_call_id\":\"outer-call\",\"content\":[",
"{\"type\":\"web_fetch_tool_result\",\"tool_use_id\":\"srvtoolu_inner\",",
"\"content\":{\"type\":\"web_fetch_result\",\"url\":\"https://u/\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("outer-call"));
}
#[test]
fn code_execution_tool_result_block_renders_success_behind_distinct_prefix() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"code_execution_tool_result\",\"tool_use_id\":\"srvtoolu_ce_01\",",
"\"content\":{\"type\":\"code_execution_result\",\"stdout\":\"Hello, World!\",",
"\"stderr\":\"\",\"return_code\":0}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [code_execution_result] {\"return_code\":0,\"stdout\":\"Hello, World!\"}"
);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("srvtoolu_ce_01"));
}
#[test]
fn code_execution_tool_result_block_includes_stderr_when_non_blank() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"code_execution_tool_result\",\"tool_use_id\":\"srvtoolu_ce_02\",",
"\"content\":{\"type\":\"code_execution_result\",",
"\"stdout\":\"partial output\",\"stderr\":\"oops bad call\",\"return_code\":2}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [code_execution_result] \
{\"return_code\":2,\"stderr\":\"oops bad call\",\"stdout\":\"partial output\"}"
);
}
#[test]
fn code_execution_tool_result_block_with_return_code_zero_kept() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"code_execution_tool_result\",\"tool_use_id\":\"srvtoolu_ce_03\",",
"\"content\":{\"type\":\"code_execution_result\",",
"\"stdout\":\"\",\"stderr\":\"\",\"return_code\":0}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [code_execution_result] {\"return_code\":0}"
);
}
#[test]
fn code_execution_tool_result_block_error_renders_behind_error_prefix() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"code_execution_tool_result\",\"tool_use_id\":\"srvtoolu_ce_04\",",
"\"content\":{\"type\":\"code_execution_tool_result_error\",",
"\"error_code\":\"unavailable\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [code_execution_error] error_code=unavailable"
);
assert!(!chunks[0].text.contains("[tool_error]"));
assert!(!chunks[0].text.contains("[mcp_tool_error]"));
assert!(!chunks[0].text.contains("[web_search_tool_error]"));
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("srvtoolu_ce_04"));
}
#[test]
fn code_execution_tool_result_block_with_no_useful_fields_drops() {
let no_fields = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"code_execution_tool_result\",\"tool_use_id\":\"srvtoolu_ce_05\",",
"\"content\":{\"type\":\"code_execution_result\"}}",
"]}\n"
);
assert!(extract_jsonl(no_fields).is_empty());
let stringy_rc = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"code_execution_tool_result\",\"tool_use_id\":\"srvtoolu_ce_06\",",
"\"content\":{\"type\":\"code_execution_result\",\"return_code\":\"zero\"}}",
"]}\n"
);
assert!(extract_jsonl(stringy_rc).is_empty());
let error_no_code = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"code_execution_tool_result\",\"tool_use_id\":\"srvtoolu_ce_07\",",
"\"content\":{\"type\":\"code_execution_tool_result_error\"}}",
"]}\n"
);
assert!(extract_jsonl(error_no_code).is_empty());
let missing_content = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"code_execution_tool_result\",\"tool_use_id\":\"srvtoolu_ce_08\"}",
"]}\n"
);
assert!(extract_jsonl(missing_content).is_empty());
let unknown_inner_type = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"code_execution_tool_result\",\"tool_use_id\":\"srvtoolu_ce_09\",",
"\"content\":{\"type\":\"some_future_shape\",\"stdout\":\"ignored\"}}",
"]}\n"
);
assert!(extract_jsonl(unknown_inner_type).is_empty());
}
#[test]
fn code_execution_tool_result_block_text_field_still_wins() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"code_execution_tool_result\",\"text\":\"direct text wins\",",
"\"content\":{\"type\":\"code_execution_result\",\"return_code\":0,",
"\"stdout\":\"ignored\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] direct text wins");
}
#[test]
fn code_execution_tool_result_block_interleaves_with_other_blocks_in_join_order() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"text\":\"running the snippet\"},",
"{\"type\":\"code_execution_tool_result\",\"tool_use_id\":\"srvtoolu_ce_mix\",",
"\"content\":{\"type\":\"code_execution_result\",\"stdout\":\"42\",\"return_code\":0}},",
"{\"type\":\"text\",\"text\":\"that's the answer\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] running the snippet\n\
[code_execution_result] {\"return_code\":0,\"stdout\":\"42\"}\n\
that's the answer"
);
}
#[test]
fn non_code_execution_typed_block_does_not_trigger_code_execution_prefix() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"text\":\"plain prose\",",
"\"content\":{\"type\":\"code_execution_result\",\"stdout\":\"should not surface\",",
"\"return_code\":0}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] plain prose");
assert!(!chunks[0].text.contains("[code_execution_result]"));
}
#[test]
fn code_execution_tool_result_block_recovers_tool_call_id_when_outer_missing() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"code_execution_tool_result\",\"tool_use_id\":\"srvtoolu_ce_recovered\",",
"\"content\":{\"type\":\"code_execution_result\",\"stdout\":\"ok\",\"return_code\":0}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].tool_call_id.as_deref(),
Some("srvtoolu_ce_recovered")
);
}
#[test]
fn code_execution_tool_result_block_does_not_widen_to_top_level_id() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"code_execution_tool_result\",\"id\":\"not-a-call-id\",",
"\"content\":{\"type\":\"code_execution_result\",\"stdout\":\"ok\",\"return_code\":0}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert!(chunks[0].tool_call_id.is_none());
}
#[test]
fn outer_tool_call_id_wins_over_nested_code_execution_tool_result_block() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"tool_call_id\":\"outer-call\",\"content\":[",
"{\"type\":\"code_execution_tool_result\",\"tool_use_id\":\"srvtoolu_ce_inner\",",
"\"content\":{\"type\":\"code_execution_result\",\"stdout\":\"ok\",\"return_code\":0}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("outer-call"));
}
#[test]
fn code_execution_tool_result_block_surfaces_nested_output_file_ids() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"code_execution_tool_result\",\"tool_use_id\":\"srvtoolu_ce_files\",",
"\"content\":{\"type\":\"code_execution_result\",\"stdout\":\"plot saved\",",
"\"return_code\":0,\"content\":[",
"{\"type\":\"code_execution_output\",\"file_id\":\"file_chart_one\"},",
"{\"type\":\"code_execution_output\",\"file_id\":\"file_chart_two\"}",
"]}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [code_execution_result] {\"return_code\":0,\"stdout\":\"plot saved\"}\n\
[code_execution_output] file_chart_one\n\
[code_execution_output] file_chart_two"
);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("srvtoolu_ce_files"));
}
#[test]
fn code_execution_tool_result_block_renders_outputs_with_bare_result_prefix() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"code_execution_tool_result\",\"tool_use_id\":\"srvtoolu_ce_only_files\",",
"\"content\":{\"type\":\"code_execution_result\",\"content\":[",
"{\"type\":\"code_execution_output\",\"file_id\":\"file_only_one\"}",
"]}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [code_execution_result]\n\
[code_execution_output] file_only_one"
);
}
#[test]
fn code_execution_output_entries_drop_when_anchorless_or_unknown_type() {
let mixed = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"code_execution_tool_result\",\"tool_use_id\":\"srvtoolu_ce_mixed\",",
"\"content\":{\"type\":\"code_execution_result\",\"stdout\":\"ok\",\"return_code\":0,",
"\"content\":[",
"{\"type\":\"code_execution_output\",\"file_id\":\"file_kept\"},",
"{\"type\":\"code_execution_output\"},",
"{\"type\":\"code_execution_output\",\"file_id\":\"\"},",
"{\"type\":\"some_future_shape\",\"file_id\":\"file_ignored\"}",
"]}}",
"]}\n"
);
let chunks = extract_jsonl(mixed);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [code_execution_result] {\"return_code\":0,\"stdout\":\"ok\"}\n\
[code_execution_output] file_kept"
);
let all_unusable = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"code_execution_tool_result\",\"tool_use_id\":\"srvtoolu_ce_drop\",",
"\"content\":{\"type\":\"code_execution_result\",\"content\":[",
"{\"type\":\"code_execution_output\"},",
"{\"type\":\"some_future_shape\",\"file_id\":\"file_ignored\"}",
"]}}",
"]}\n"
);
assert!(extract_jsonl(all_unusable).is_empty());
}
#[test]
fn code_execution_tool_result_inner_content_string_falls_through_unchanged() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"code_execution_tool_result\",\"tool_use_id\":\"srvtoolu_ce_string\",",
"\"content\":{\"type\":\"code_execution_result\",\"content\":\"not an array\"}}",
"]}\n"
);
assert!(extract_jsonl(jsonl).is_empty());
}
#[test]
fn bash_code_execution_tool_result_block_renders_success_behind_distinct_prefix() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"bash_code_execution_tool_result\",\"tool_use_id\":\"srvtoolu_bash_01\",",
"\"content\":{\"type\":\"bash_code_execution_result\",\"stdout\":\"hello world\\n\",",
"\"stderr\":\"\",\"return_code\":0}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [bash_code_execution_result] \
{\"return_code\":0,\"stdout\":\"hello world\\n\"}"
);
assert!(!chunks[0].text.contains("[code_execution_result]"));
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("srvtoolu_bash_01"));
}
#[test]
fn bash_code_execution_tool_result_block_includes_stderr_when_non_blank() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"bash_code_execution_tool_result\",\"tool_use_id\":\"srvtoolu_bash_02\",",
"\"content\":{\"type\":\"bash_code_execution_result\",",
"\"stdout\":\"some output\",\"stderr\":\"warning: deprecated\",\"return_code\":1}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [bash_code_execution_result] \
{\"return_code\":1,\"stderr\":\"warning: deprecated\",\"stdout\":\"some output\"}"
);
}
#[test]
fn bash_code_execution_tool_result_block_with_return_code_zero_kept() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"bash_code_execution_tool_result\",\"tool_use_id\":\"srvtoolu_bash_03\",",
"\"content\":{\"type\":\"bash_code_execution_result\",",
"\"stdout\":\"\",\"stderr\":\"\",\"return_code\":0}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [bash_code_execution_result] {\"return_code\":0}"
);
}
#[test]
fn bash_code_execution_tool_result_block_error_renders_behind_distinct_error_prefix() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"bash_code_execution_tool_result\",\"tool_use_id\":\"srvtoolu_bash_04\",",
"\"content\":{\"type\":\"bash_code_execution_tool_result_error\",",
"\"error_code\":\"unavailable\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [bash_code_execution_error] error_code=unavailable"
);
assert!(!chunks[0].text.contains("[code_execution_error]"));
assert!(!chunks[0].text.contains("[tool_error]"));
assert!(!chunks[0].text.contains("[mcp_tool_error]"));
assert!(!chunks[0].text.contains("[web_search_tool_error]"));
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("srvtoolu_bash_04"));
}
#[test]
fn bash_code_execution_tool_result_block_with_no_useful_fields_drops() {
let no_fields = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"bash_code_execution_tool_result\",\"tool_use_id\":\"srvtoolu_bash_05\",",
"\"content\":{\"type\":\"bash_code_execution_result\"}}",
"]}\n"
);
assert!(extract_jsonl(no_fields).is_empty());
let stringy_rc = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"bash_code_execution_tool_result\",\"tool_use_id\":\"srvtoolu_bash_06\",",
"\"content\":{\"type\":\"bash_code_execution_result\",\"return_code\":\"zero\"}}",
"]}\n"
);
assert!(extract_jsonl(stringy_rc).is_empty());
let error_no_code = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"bash_code_execution_tool_result\",\"tool_use_id\":\"srvtoolu_bash_07\",",
"\"content\":{\"type\":\"bash_code_execution_tool_result_error\"}}",
"]}\n"
);
assert!(extract_jsonl(error_no_code).is_empty());
let missing_content = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"bash_code_execution_tool_result\",\"tool_use_id\":\"srvtoolu_bash_08\"}",
"]}\n"
);
assert!(extract_jsonl(missing_content).is_empty());
let unknown_inner_type = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"bash_code_execution_tool_result\",\"tool_use_id\":\"srvtoolu_bash_09\",",
"\"content\":{\"type\":\"code_execution_result\",\"stdout\":\"ignored\"}}",
"]}\n"
);
assert!(extract_jsonl(unknown_inner_type).is_empty());
}
#[test]
fn bash_code_execution_tool_result_block_text_field_still_wins() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"bash_code_execution_tool_result\",\"text\":\"direct text wins\",",
"\"content\":{\"type\":\"bash_code_execution_result\",\"return_code\":0,",
"\"stdout\":\"ignored\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] direct text wins");
}
#[test]
fn bash_code_execution_tool_result_block_interleaves_with_other_blocks_in_join_order() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"text\":\"running ls\"},",
"{\"type\":\"bash_code_execution_tool_result\",\"tool_use_id\":\"srvtoolu_bash_mix\",",
"\"content\":{\"type\":\"bash_code_execution_result\",\"stdout\":\"README.md\",\"return_code\":0}},",
"{\"type\":\"text\",\"text\":\"so just one file\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] running ls\n\
[bash_code_execution_result] {\"return_code\":0,\"stdout\":\"README.md\"}\n\
so just one file"
);
}
#[test]
fn non_bash_code_execution_typed_block_does_not_trigger_bash_prefix() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"text\",\"text\":\"plain prose\",",
"\"content\":{\"type\":\"bash_code_execution_result\",\"stdout\":\"should not surface\",",
"\"return_code\":0}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] plain prose");
assert!(!chunks[0].text.contains("[bash_code_execution_result]"));
}
#[test]
fn bash_code_execution_tool_result_block_recovers_tool_call_id_when_outer_missing() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"bash_code_execution_tool_result\",\"tool_use_id\":\"srvtoolu_bash_recovered\",",
"\"content\":{\"type\":\"bash_code_execution_result\",\"stdout\":\"ok\",\"return_code\":0}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].tool_call_id.as_deref(),
Some("srvtoolu_bash_recovered")
);
}
#[test]
fn bash_code_execution_tool_result_block_does_not_widen_to_top_level_id() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"bash_code_execution_tool_result\",\"id\":\"not-a-call-id\",",
"\"content\":{\"type\":\"bash_code_execution_result\",\"stdout\":\"ok\",\"return_code\":0}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert!(chunks[0].tool_call_id.is_none());
}
#[test]
fn outer_tool_call_id_wins_over_nested_bash_code_execution_tool_result_block() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"tool_call_id\":\"outer-bash-call\",\"content\":[",
"{\"type\":\"bash_code_execution_tool_result\",\"tool_use_id\":\"srvtoolu_bash_inner\",",
"\"content\":{\"type\":\"bash_code_execution_result\",\"stdout\":\"ok\",\"return_code\":0}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("outer-bash-call"));
}
#[test]
fn search_result_block_renders_source_title_and_inner_text_behind_distinct_prefix() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"search_result\",\"source\":\"https://docs.example/lantern\",",
"\"title\":\"Lantern overview\",\"content\":[",
"{\"type\":\"text\",\"text\":\"provenance-aware local memory engine\"}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[user] [search_result] https://docs.example/lantern Lantern overview\nprovenance-aware local memory engine"
);
}
#[test]
fn search_result_block_with_source_only_renders_single_anchor_header() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"search_result\",\"source\":\"doc-123\",\"content\":[",
"{\"type\":\"text\",\"text\":\"matched excerpt\"}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[user] [search_result] doc-123\nmatched excerpt"
);
}
#[test]
fn search_result_block_with_title_only_renders_single_anchor_header() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"search_result\",\"title\":\"Untitled doc\",\"content\":[",
"{\"type\":\"text\",\"text\":\"matched excerpt\"}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[user] [search_result] Untitled doc\nmatched excerpt"
);
}
#[test]
fn search_result_block_without_anchors_falls_through_to_generic_content_recursion() {
let jsonl_with_inner = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"search_result\",\"content\":[",
"{\"type\":\"text\",\"text\":\"matched excerpt\"}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl_with_inner);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] matched excerpt");
assert!(
!chunks[0].text.contains("[search_result]"),
"anchorless blocks must not get the new prefix"
);
let jsonl_no_inner = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"search_result\"}",
"]}\n"
);
assert!(extract_jsonl(jsonl_no_inner).is_empty());
let jsonl_blank_anchors = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"search_result\",\"source\":\" \",\"title\":\"\",\"content\":[",
"{\"type\":\"text\",\"text\":\"matched\"}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl_blank_anchors);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] matched");
}
#[test]
fn search_result_block_with_anchors_and_no_inner_content_renders_header_only() {
let jsonl_missing_content = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"search_result\",\"source\":\"https://docs.example/a\",",
"\"title\":\"Doc A\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl_missing_content);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[user] [search_result] https://docs.example/a Doc A"
);
let jsonl_empty_array = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"search_result\",\"source\":\"https://docs.example/b\",",
"\"title\":\"Doc B\",\"content\":[]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl_empty_array);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[user] [search_result] https://docs.example/b Doc B"
);
}
#[test]
fn search_result_block_with_string_content_flows_through_content_to_text() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"search_result\",\"source\":\"src-1\",\"title\":\"T\",",
"\"content\":\"plain string body\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[user] [search_result] src-1 T\nplain string body"
);
}
#[test]
fn search_result_block_text_field_still_wins() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"search_result\",\"source\":\"src\",\"title\":\"T\",",
"\"text\":\"direct text wins\",\"content\":[",
"{\"type\":\"text\",\"text\":\"ignored\"}",
"]}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] direct text wins");
assert!(
!chunks[0].text.contains("[search_result]"),
"direct text field must not get the search_result prefix"
);
}
#[test]
fn non_search_result_typed_block_does_not_trigger_search_result_prefix() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"text\",\"source\":\"src\",\"title\":\"T\",",
"\"text\":\"plain text\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] plain text");
assert!(
!chunks[0].text.contains("[search_result]"),
"non-search_result blocks must not get the new prefix"
);
}
#[test]
fn search_result_block_interleaves_with_other_blocks_in_join_order() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":[",
"{\"type\":\"text\",\"text\":\"context before\"},",
"{\"type\":\"search_result\",\"source\":\"src-x\",\"title\":\"T-x\",",
"\"content\":[{\"type\":\"text\",\"text\":\"matched body\"}]},",
"{\"type\":\"text\",\"text\":\"context after\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[user] context before\n[search_result] src-x T-x\nmatched body\ncontext after"
);
}
#[test]
fn web_search_call_line_with_search_action_renders_behind_distinct_prefix() {
let jsonl = concat!(
"{\"type\":\"web_search_call\",\"id\":\"ws_abc123\",\"status\":\"completed\",",
"\"action\":{\"type\":\"search\",\"query\":\"latest news about AI\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[web_search_call:search] {\"query\":\"latest news about AI\"}"
);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("ws_abc123"));
}
#[test]
fn web_search_call_line_with_open_page_action_uses_url_anchor() {
let jsonl = concat!(
"{\"type\":\"web_search_call\",\"id\":\"ws_open_1\",",
"\"action\":{\"type\":\"open_page\",\"url\":\"https://example.com/page\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[web_search_call:open_page] {\"url\":\"https://example.com/page\"}"
);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("ws_open_1"));
}
#[test]
fn web_search_call_line_with_find_in_page_action_uses_pattern_and_url_anchors() {
let jsonl = concat!(
"{\"type\":\"web_search_call\",\"id\":\"ws_find_1\",",
"\"action\":{\"type\":\"find_in_page\",\"pattern\":\"async runtime\",",
"\"url\":\"https://docs.example/tokio\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[web_search_call:find_in_page] {\"pattern\":\"async runtime\",\"url\":\"https://docs.example/tokio\"}"
);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("ws_find_1"));
}
#[test]
fn web_search_call_line_with_find_in_page_pattern_only_renders_pattern_anchor() {
let jsonl = concat!(
"{\"type\":\"web_search_call\",\"id\":\"ws_find_2\",",
"\"action\":{\"type\":\"find_in_page\",\"pattern\":\"needle in haystack\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[web_search_call:find_in_page] {\"pattern\":\"needle in haystack\"}"
);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("ws_find_2"));
}
#[test]
fn web_search_call_line_filtered_body_has_deterministic_sorted_keys() {
let jsonl = concat!(
"{\"type\":\"web_search_call\",\"id\":\"ws_sort\",",
"\"action\":{\"type\":\"search\",\"url\":\"https://u/\",\"query\":\"q\",",
"\"pattern\":\"p\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[web_search_call:search] {\"pattern\":\"p\",\"query\":\"q\",\"url\":\"https://u/\"}"
);
}
#[test]
fn web_search_call_line_does_not_dump_large_optional_arrays() {
let jsonl = concat!(
"{\"type\":\"web_search_call\",\"id\":\"ws_filter\",",
"\"action\":{\"type\":\"search\",\"query\":\"q\",",
"\"sources\":[{\"url\":\"https://big.example/1\",\"snippet\":\"NOISE_BLOB_A\"},",
"{\"url\":\"https://big.example/2\",\"snippet\":\"NOISE_BLOB_B\"}],",
"\"results\":[\"r1\",\"r2\",\"r3\"]}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[web_search_call:search] {\"query\":\"q\"}");
assert!(!chunks[0].text.contains("NOISE_BLOB_A"));
assert!(!chunks[0].text.contains("NOISE_BLOB_B"));
assert!(!chunks[0].text.contains("sources"));
assert!(!chunks[0].text.contains("results"));
}
#[test]
fn web_search_call_line_with_no_anchor_emits_bare_action_prefix() {
let jsonl = concat!(
"{\"type\":\"web_search_call\",\"id\":\"ws_bare\",",
"\"action\":{\"type\":\"reasoning\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[web_search_call:reasoning]");
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("ws_bare"));
}
#[test]
fn web_search_call_line_with_missing_action_type_drops() {
let missing_action_type = concat!(
"{\"type\":\"web_search_call\",\"id\":\"ws_no_type\",",
"\"action\":{\"query\":\"q\"}}\n"
);
assert!(extract_jsonl(missing_action_type).is_empty());
let blank_action_type = concat!(
"{\"type\":\"web_search_call\",\"id\":\"ws_blank_type\",",
"\"action\":{\"type\":\" \",\"query\":\"q\"}}\n"
);
assert!(extract_jsonl(blank_action_type).is_empty());
let missing_action = "{\"type\":\"web_search_call\",\"id\":\"ws_no_action\"}\n";
assert!(extract_jsonl(missing_action).is_empty());
}
#[test]
fn web_search_call_line_existing_content_still_wins() {
let jsonl = concat!(
"{\"type\":\"web_search_call\",\"id\":\"ws_content\",",
"\"content\":\"direct content wins\",",
"\"action\":{\"type\":\"search\",\"query\":\"q\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "direct content wins");
assert!(!chunks[0].text.contains("[web_search_call:search]"));
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("ws_content"));
}
#[test]
fn web_search_call_line_id_widening_is_type_narrowed() {
let jsonl = "{\"role\":\"user\",\"id\":\"msg_42\",\"content\":\"hello\"}\n";
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert!(chunks[0].tool_call_id.is_none());
}
#[test]
fn non_web_search_call_type_does_not_trigger_prefix() {
let jsonl = concat!(
"{\"type\":\"message\",\"role\":\"assistant\",\"content\":\"hi\",",
"\"action\":{\"type\":\"search\",\"query\":\"ignored\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] hi");
assert!(!chunks[0].text.contains("[web_search_call:"));
}
#[test]
fn web_search_call_in_message_envelope_is_extracted() {
let jsonl = concat!(
"{\"sessionId\":\"sess-1\",\"message\":{",
"\"type\":\"web_search_call\",\"id\":\"ws_envelope\",",
"\"action\":{\"type\":\"search\",\"query\":\"q\"}}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[web_search_call:search] {\"query\":\"q\"}");
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("ws_envelope"));
assert_eq!(chunks[0].session_id.as_deref(), Some("sess-1"));
}
#[test]
fn outer_tool_call_id_wins_over_web_search_call_line_id() {
let jsonl = concat!(
"{\"type\":\"web_search_call\",\"id\":\"ws_inner\",",
"\"tool_call_id\":\"outer-call\",",
"\"action\":{\"type\":\"search\",\"query\":\"q\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("outer-call"));
}
#[test]
fn file_search_call_line_renders_behind_distinct_prefix_with_queries() {
let jsonl = concat!(
"{\"type\":\"file_search_call\",\"id\":\"fs_abc123\",\"status\":\"completed\",",
"\"queries\":[\"how do lanterns work\"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[file_search_call] {\"queries\":[\"how do lanterns work\"]}"
);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("fs_abc123"));
}
#[test]
fn file_search_call_line_joins_multiple_queries_in_order() {
let jsonl = concat!(
"{\"type\":\"file_search_call\",\"id\":\"fs_multi\",",
"\"queries\":[\"first query\",\"\",\"second query\",\" \"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[file_search_call] {\"queries\":[\"first query\",\"second query\"]}"
);
}
#[test]
fn file_search_call_line_does_not_dump_results_snippet_text() {
let jsonl = concat!(
"{\"type\":\"file_search_call\",\"id\":\"fs_with_results\",",
"\"queries\":[\"q\"],",
"\"results\":[{\"file_id\":\"file_1\",\"text\":\"NOISE_BLOB_FILE_CONTENT\"},",
"{\"file_id\":\"file_2\",\"text\":\"NOISE_BLOB_FILE_CONTENT_TWO\"}]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[file_search_call] {\"queries\":[\"q\"]}\n[file_search_result] file_1\n[file_search_result] file_2"
);
assert!(!chunks[0].text.contains("NOISE_BLOB_FILE_CONTENT"));
}
#[test]
fn file_search_call_result_renders_both_anchors() {
let jsonl = concat!(
"{\"type\":\"file_search_call\",\"id\":\"fs_anchors\",",
"\"queries\":[\"q\"],",
"\"results\":[{\"file_id\":\"file_abc\",\"filename\":\"notes.md\",",
"\"score\":0.95,\"attributes\":{\"k\":\"v\"}}]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[file_search_call] {\"queries\":[\"q\"]}\n[file_search_result] file_abc notes.md"
);
assert!(!chunks[0].text.contains("0.95"));
assert!(!chunks[0].text.contains("attributes"));
}
#[test]
fn file_search_call_result_renders_file_id_only_fallback() {
let jsonl = concat!(
"{\"type\":\"file_search_call\",\"id\":\"fs_id_only\",",
"\"queries\":[\"q\"],",
"\"results\":[{\"file_id\":\"file_solo\"}]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[file_search_call] {\"queries\":[\"q\"]}\n[file_search_result] file_solo"
);
}
#[test]
fn file_search_call_result_renders_filename_only_fallback() {
let jsonl = concat!(
"{\"type\":\"file_search_call\",\"id\":\"fs_name_only\",",
"\"queries\":[\"q\"],",
"\"results\":[{\"filename\":\"orphan.txt\"}]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[file_search_call] {\"queries\":[\"q\"]}\n[file_search_result] orphan.txt"
);
}
#[test]
fn file_search_call_result_with_neither_anchor_drops_entry() {
let jsonl = concat!(
"{\"type\":\"file_search_call\",\"id\":\"fs_mixed\",",
"\"queries\":[\"q\"],",
"\"results\":[",
"{\"text\":\"snippet only\",\"score\":0.5},",
"{\"file_id\":\"file_kept\",\"filename\":\"kept.md\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[file_search_call] {\"queries\":[\"q\"]}\n[file_search_result] file_kept kept.md"
);
assert!(!chunks[0].text.contains("snippet"));
}
#[test]
fn file_search_call_results_join_in_array_order() {
let jsonl = concat!(
"{\"type\":\"file_search_call\",\"id\":\"fs_multi_res\",",
"\"queries\":[\"q\"],",
"\"results\":[",
"{\"file_id\":\"file_a\",\"filename\":\"a.md\"},",
"{\"file_id\":\"file_b\"},",
"{\"filename\":\"c.txt\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
concat!(
"[file_search_call] {\"queries\":[\"q\"]}\n",
"[file_search_result] file_a a.md\n",
"[file_search_result] file_b\n",
"[file_search_result] c.txt"
)
);
}
#[test]
fn file_search_call_empty_results_array_keeps_call_line_only() {
let empty = concat!(
"{\"type\":\"file_search_call\",\"id\":\"fs_empty_res\",",
"\"queries\":[\"q\"],\"results\":[]}\n"
);
let chunks = extract_jsonl(empty);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[file_search_call] {\"queries\":[\"q\"]}");
let only_anchorless = concat!(
"{\"type\":\"file_search_call\",\"id\":\"fs_anchorless\",",
"\"queries\":[\"q\"],",
"\"results\":[{\"text\":\"snippet\",\"score\":0.5}]}\n"
);
let chunks = extract_jsonl(only_anchorless);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[file_search_call] {\"queries\":[\"q\"]}");
}
#[test]
fn file_search_call_line_with_no_usable_queries_drops() {
let missing_queries = "{\"type\":\"file_search_call\",\"id\":\"fs_no_q\"}\n";
assert!(extract_jsonl(missing_queries).is_empty());
let empty_array =
concat!("{\"type\":\"file_search_call\",\"id\":\"fs_empty\",\"queries\":[]}\n");
assert!(extract_jsonl(empty_array).is_empty());
let all_blank = concat!(
"{\"type\":\"file_search_call\",\"id\":\"fs_blank\",",
"\"queries\":[\"\",\" \"]}\n"
);
assert!(extract_jsonl(all_blank).is_empty());
let non_string_only = concat!(
"{\"type\":\"file_search_call\",\"id\":\"fs_non_string\",",
"\"queries\":[42,true,null]}\n"
);
assert!(extract_jsonl(non_string_only).is_empty());
}
#[test]
fn file_search_call_line_existing_content_still_wins() {
let jsonl = concat!(
"{\"type\":\"file_search_call\",\"id\":\"fs_content\",",
"\"content\":\"direct content wins\",",
"\"queries\":[\"q\"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "direct content wins");
assert!(!chunks[0].text.contains("[file_search_call]"));
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("fs_content"));
}
#[test]
fn file_search_call_line_id_widening_is_type_narrowed() {
let jsonl = concat!(
"{\"type\":\"message\",\"role\":\"user\",\"id\":\"msg_42\",",
"\"content\":\"hello\",\"queries\":[\"ignored\"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert!(chunks[0].tool_call_id.is_none());
}
#[test]
fn non_file_search_call_type_does_not_trigger_prefix() {
let jsonl = concat!(
"{\"type\":\"message\",\"role\":\"assistant\",\"content\":\"hi\",",
"\"queries\":[\"ignored\"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] hi");
assert!(!chunks[0].text.contains("[file_search_call]"));
}
#[test]
fn file_search_call_in_message_envelope_is_extracted() {
let jsonl = concat!(
"{\"sessionId\":\"sess-1\",\"message\":{",
"\"type\":\"file_search_call\",\"id\":\"fs_envelope\",",
"\"queries\":[\"q\"]}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[file_search_call] {\"queries\":[\"q\"]}");
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("fs_envelope"));
assert_eq!(chunks[0].session_id.as_deref(), Some("sess-1"));
}
#[test]
fn outer_tool_call_id_wins_over_file_search_call_line_id() {
let jsonl = concat!(
"{\"type\":\"file_search_call\",\"id\":\"fs_inner\",",
"\"tool_call_id\":\"outer-call\",\"queries\":[\"q\"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("outer-call"));
}
#[test]
fn code_interpreter_call_line_renders_with_code_anchor() {
let jsonl = concat!(
"{\"type\":\"code_interpreter_call\",\"id\":\"ci_abc123\",",
"\"status\":\"completed\",\"container_id\":\"cntr_xyz\",",
"\"code\":\"import pandas as pd\\nprint(df.head())\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[code_interpreter_call] import pandas as pd\nprint(df.head())"
);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("ci_abc123"));
}
#[test]
fn code_interpreter_call_line_drops_container_id_and_status() {
let jsonl = concat!(
"{\"type\":\"code_interpreter_call\",\"id\":\"ci_drop\",",
"\"status\":\"completed\",\"container_id\":\"cntr_should_not_appear\",",
"\"code\":\"print('hi')\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[code_interpreter_call] print('hi')");
assert!(!chunks[0].text.contains("cntr_should_not_appear"));
assert!(!chunks[0].text.contains("completed"));
}
#[test]
fn code_interpreter_call_line_missing_or_blank_code_drops() {
let missing = "{\"type\":\"code_interpreter_call\",\"id\":\"ci_missing\"}\n";
assert!(extract_jsonl(missing).is_empty());
let empty = "{\"type\":\"code_interpreter_call\",\"id\":\"ci_empty\",\"code\":\"\"}\n";
assert!(extract_jsonl(empty).is_empty());
let blank = "{\"type\":\"code_interpreter_call\",\"id\":\"ci_blank\",\"code\":\" \"}\n";
assert!(extract_jsonl(blank).is_empty());
}
#[test]
fn code_interpreter_call_line_existing_content_still_wins() {
let jsonl = concat!(
"{\"type\":\"code_interpreter_call\",\"id\":\"ci_content\",",
"\"content\":\"direct content wins\",\"code\":\"print('hi')\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "direct content wins");
assert!(!chunks[0].text.contains("[code_interpreter_call]"));
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("ci_content"));
}
#[test]
fn code_interpreter_call_line_id_widening_is_type_narrowed() {
let jsonl = concat!(
"{\"type\":\"message\",\"role\":\"user\",\"id\":\"msg_42\",",
"\"content\":\"hello\",\"code\":\"ignored\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert!(chunks[0].tool_call_id.is_none());
}
#[test]
fn non_code_interpreter_call_type_does_not_trigger_prefix() {
let jsonl = concat!(
"{\"type\":\"message\",\"role\":\"assistant\",\"content\":\"hi\",",
"\"code\":\"print('x')\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] hi");
assert!(!chunks[0].text.contains("[code_interpreter_call]"));
}
#[test]
fn code_interpreter_call_in_message_envelope_is_extracted() {
let jsonl = concat!(
"{\"sessionId\":\"sess-1\",\"message\":{",
"\"type\":\"code_interpreter_call\",\"id\":\"ci_envelope\",",
"\"code\":\"print('hi')\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[code_interpreter_call] print('hi')");
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("ci_envelope"));
assert_eq!(chunks[0].session_id.as_deref(), Some("sess-1"));
}
#[test]
fn outer_tool_call_id_wins_over_code_interpreter_call_line_id() {
let jsonl = concat!(
"{\"type\":\"code_interpreter_call\",\"id\":\"ci_inner\",",
"\"tool_call_id\":\"outer-call\",\"code\":\"print('hi')\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("outer-call"));
}
#[test]
fn code_interpreter_call_line_surfaces_inline_logs_output() {
let jsonl = concat!(
"{\"type\":\"code_interpreter_call\",\"id\":\"ci_logs\",",
"\"code\":\"print('hello')\",",
"\"outputs\":[{\"type\":\"logs\",\"logs\":\"hello\\n\"}]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[code_interpreter_call] print('hello')\n[code_interpreter_logs] hello\n"
);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("ci_logs"));
}
#[test]
fn code_interpreter_call_line_outputs_join_in_array_order() {
let jsonl = concat!(
"{\"type\":\"code_interpreter_call\",\"id\":\"ci_multi\",",
"\"code\":\"step()\",\"outputs\":[",
"{\"type\":\"logs\",\"logs\":\"first\"},",
"{\"type\":\"logs\",\"logs\":\"second\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
concat!(
"[code_interpreter_call] step()\n",
"[code_interpreter_logs] first\n",
"[code_interpreter_logs] second"
)
);
}
#[test]
fn code_interpreter_call_line_image_output_url_anchor() {
let jsonl = concat!(
"{\"type\":\"code_interpreter_call\",\"id\":\"ci_img_url\",",
"\"code\":\"plot()\",\"outputs\":[",
"{\"type\":\"image\",\"url\":\"https://example.com/plot.png\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[code_interpreter_call] plot()\n[code_interpreter_image] https://example.com/plot.png"
);
}
#[test]
fn code_interpreter_call_line_image_data_url_strips_base64() {
let jsonl = concat!(
"{\"type\":\"code_interpreter_call\",\"id\":\"ci_img_data\",",
"\"code\":\"plot()\",\"outputs\":[",
"{\"type\":\"image\",\"url\":\"data:image/png;base64,iVBORw0KGgoBASE64BYTES\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[code_interpreter_call] plot()\n[code_interpreter_image:image/png]"
);
assert!(!chunks[0].text.contains("iVBORw0KGgoBASE64BYTES"));
assert!(!chunks[0].text.contains("base64"));
}
#[test]
fn code_interpreter_call_line_image_file_id_anchor() {
let jsonl = concat!(
"{\"type\":\"code_interpreter_call\",\"id\":\"ci_img_file\",",
"\"code\":\"plot()\",\"outputs\":[",
"{\"type\":\"image\",\"file_id\":\"file_chart_42\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[code_interpreter_call] plot()\n[code_interpreter_image:file] file_chart_42"
);
}
#[test]
fn code_interpreter_call_line_image_malformed_data_url_falls_back_to_file_id() {
let jsonl = concat!(
"{\"type\":\"code_interpreter_call\",\"id\":\"ci_img_bad_data\",",
"\"code\":\"plot()\",\"outputs\":[",
"{\"type\":\"image\",\"url\":\"data:malformedNoSeparator\",",
"\"file_id\":\"file_fallback\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[code_interpreter_call] plot()\n[code_interpreter_image:file] file_fallback"
);
assert!(!chunks[0].text.contains("malformedNoSeparator"));
}
#[test]
fn code_interpreter_call_line_anchorless_outputs_drop() {
let jsonl = concat!(
"{\"type\":\"code_interpreter_call\",\"id\":\"ci_drop_outputs\",",
"\"code\":\"step()\",\"outputs\":[",
"{\"type\":\"logs\"},",
"{\"type\":\"logs\",\"logs\":\"\"},",
"{\"type\":\"logs\",\"logs\":\" \"},",
"{\"type\":\"image\"},",
"{\"type\":\"future_kind\",\"text\":\"ignored\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[code_interpreter_call] step()");
assert!(!chunks[0].text.contains("[code_interpreter_logs]"));
assert!(!chunks[0].text.contains("[code_interpreter_image]"));
}
#[test]
fn code_interpreter_call_line_empty_outputs_array_keeps_code_line() {
let jsonl = concat!(
"{\"type\":\"code_interpreter_call\",\"id\":\"ci_empty_out\",",
"\"code\":\"print('hi')\",\"outputs\":[]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[code_interpreter_call] print('hi')");
}
#[test]
fn code_interpreter_call_line_outputs_cannot_rescue_missing_code() {
let jsonl = concat!(
"{\"type\":\"code_interpreter_call\",\"id\":\"ci_no_code\",",
"\"outputs\":[{\"type\":\"logs\",\"logs\":\"orphan logs\"}]}\n"
);
assert!(extract_jsonl(jsonl).is_empty());
}
#[test]
fn code_interpreter_call_line_mixed_outputs_interleave() {
let jsonl = concat!(
"{\"type\":\"code_interpreter_call\",\"id\":\"ci_mixed\",",
"\"code\":\"plot()\",\"outputs\":[",
"{\"type\":\"logs\",\"logs\":\"computed\"},",
"{\"type\":\"image\",\"file_id\":\"file_chart\"},",
"{\"type\":\"logs\",\"logs\":\"done\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
concat!(
"[code_interpreter_call] plot()\n",
"[code_interpreter_logs] computed\n",
"[code_interpreter_image:file] file_chart\n",
"[code_interpreter_logs] done"
)
);
}
#[test]
fn local_shell_call_line_renders_with_command_anchor() {
let jsonl = concat!(
"{\"type\":\"local_shell_call\",\"id\":\"lsh_abc\",",
"\"call_id\":\"call_xyz\",\"status\":\"completed\",",
"\"action\":{\"type\":\"exec\",",
"\"command\":[\"bash\",\"-c\",\"ls /tmp\"]}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[local_shell_call:exec] {\"command\":[\"bash\",\"-c\",\"ls /tmp\"]}"
);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_xyz"));
}
#[test]
fn local_shell_call_line_top_level_id_is_not_widened() {
let jsonl = concat!(
"{\"type\":\"local_shell_call\",\"id\":\"lsh_no_call\",",
"\"action\":{\"type\":\"exec\",\"command\":[\"echo\",\"hi\"]}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert!(chunks[0].tool_call_id.is_none());
}
#[test]
fn local_shell_call_line_working_directory_is_anchored() {
let jsonl = concat!(
"{\"type\":\"local_shell_call\",\"call_id\":\"call_wd\",",
"\"action\":{\"type\":\"exec\",",
"\"command\":[\"ls\"],\"working_directory\":\"/tmp\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[local_shell_call:exec] {\"command\":[\"ls\"],\"working_directory\":\"/tmp\"}"
);
}
#[test]
fn local_shell_call_line_drops_env_timeout_user() {
let jsonl = concat!(
"{\"type\":\"local_shell_call\",\"call_id\":\"call_drop\",",
"\"action\":{\"type\":\"exec\",\"command\":[\"ls\"],",
"\"env\":{\"SECRET_TOKEN\":\"NOISE_ENV_VALUE\"},",
"\"timeout_ms\":30000,\"user\":\"root\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[local_shell_call:exec] {\"command\":[\"ls\"]}"
);
assert!(!chunks[0].text.contains("NOISE_ENV_VALUE"));
assert!(!chunks[0].text.contains("SECRET_TOKEN"));
assert!(!chunks[0].text.contains("30000"));
assert!(!chunks[0].text.contains("root"));
}
#[test]
fn local_shell_call_line_missing_action_drops() {
let jsonl = "{\"type\":\"local_shell_call\",\"call_id\":\"call_x\"}\n";
assert!(extract_jsonl(jsonl).is_empty());
}
#[test]
fn local_shell_call_line_missing_action_type_drops() {
let jsonl = concat!(
"{\"type\":\"local_shell_call\",\"call_id\":\"call_x\",",
"\"action\":{\"command\":[\"ls\"]}}\n"
);
assert!(extract_jsonl(jsonl).is_empty());
}
#[test]
fn local_shell_call_line_empty_command_falls_back_to_bare_prefix() {
let empty = concat!(
"{\"type\":\"local_shell_call\",\"call_id\":\"call_e\",",
"\"action\":{\"type\":\"exec\",\"command\":[]}}\n"
);
let chunks = extract_jsonl(empty);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[local_shell_call:exec]");
let all_blank = concat!(
"{\"type\":\"local_shell_call\",\"call_id\":\"call_b\",",
"\"action\":{\"type\":\"exec\",\"command\":[\"\",\" \"]}}\n"
);
let chunks = extract_jsonl(all_blank);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[local_shell_call:exec]");
}
#[test]
fn local_shell_call_line_filters_non_string_command_entries() {
let jsonl = concat!(
"{\"type\":\"local_shell_call\",\"call_id\":\"call_mix\",",
"\"action\":{\"type\":\"exec\",",
"\"command\":[\"bash\",42,null,{\"k\":\"v\"},\"ls\",[1,2]]}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[local_shell_call:exec] {\"command\":[\"bash\",\"ls\"]}"
);
}
#[test]
fn local_shell_call_line_existing_content_still_wins() {
let jsonl = concat!(
"{\"type\":\"local_shell_call\",\"call_id\":\"call_c\",",
"\"content\":\"direct content wins\",",
"\"action\":{\"type\":\"exec\",\"command\":[\"ls\"]}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "direct content wins");
assert!(!chunks[0].text.contains("[local_shell_call"));
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_c"));
}
#[test]
fn non_local_shell_call_type_does_not_trigger_prefix() {
let jsonl = concat!(
"{\"type\":\"message\",\"role\":\"assistant\",\"content\":\"hi\",",
"\"action\":{\"type\":\"exec\",\"command\":[\"ls\"]}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] hi");
assert!(!chunks[0].text.contains("[local_shell_call"));
}
#[test]
fn local_shell_call_in_message_envelope_is_extracted() {
let jsonl = concat!(
"{\"sessionId\":\"sess-1\",\"message\":{",
"\"type\":\"local_shell_call\",\"call_id\":\"call_env\",",
"\"action\":{\"type\":\"exec\",\"command\":[\"ls\"]}}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[local_shell_call:exec] {\"command\":[\"ls\"]}"
);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_env"));
assert_eq!(chunks[0].session_id.as_deref(), Some("sess-1"));
}
#[test]
fn outer_tool_call_id_wins_over_local_shell_call_inner_call_id() {
let jsonl = concat!(
"{\"type\":\"local_shell_call\",\"tool_call_id\":\"outer-call\",",
"\"call_id\":\"call_inner\",",
"\"action\":{\"type\":\"exec\",\"command\":[\"ls\"]}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("outer-call"));
}
#[test]
fn local_shell_call_output_line_renders_with_string_output() {
let jsonl = concat!(
"{\"type\":\"local_shell_call_output\",\"id\":\"lsh_out_abc\",",
"\"call_id\":\"call_xyz\",\"status\":\"completed\",",
"\"output\":\"file1.txt\\nfile2.txt\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[local_shell_call_output] file1.txt\nfile2.txt"
);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_xyz"));
}
#[test]
fn local_shell_call_output_line_renders_structured_output_deterministically() {
let jsonl = concat!(
"{\"type\":\"local_shell_call_output\",\"call_id\":\"call_struct\",",
"\"output\":{\"stdout\":\"hello\",\"return_code\":0}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[local_shell_call_output] {\"return_code\":0,\"stdout\":\"hello\"}"
);
}
#[test]
fn local_shell_call_output_line_top_level_id_is_not_widened() {
let jsonl = concat!(
"{\"type\":\"local_shell_call_output\",\"id\":\"lsh_out_no_call\",",
"\"output\":\"hi\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert!(chunks[0].tool_call_id.is_none());
}
#[test]
fn local_shell_call_output_line_missing_output_drops() {
let jsonl = concat!("{\"type\":\"local_shell_call_output\",\"call_id\":\"call_x\"}\n");
assert!(extract_jsonl(jsonl).is_empty());
}
#[test]
fn local_shell_call_output_line_blank_output_drops() {
for empty in [
"{\"type\":\"local_shell_call_output\",\"call_id\":\"call_a\",\"output\":\"\"}\n",
"{\"type\":\"local_shell_call_output\",\"call_id\":\"call_b\",\"output\":\" \"}\n",
"{\"type\":\"local_shell_call_output\",\"call_id\":\"call_c\",\"output\":{}}\n",
"{\"type\":\"local_shell_call_output\",\"call_id\":\"call_d\",\"output\":[]}\n",
] {
assert!(extract_jsonl(empty).is_empty(), "should drop: {empty:?}");
}
}
#[test]
fn local_shell_call_output_line_existing_content_still_wins() {
let jsonl = concat!(
"{\"type\":\"local_shell_call_output\",\"call_id\":\"call_c\",",
"\"content\":\"direct content wins\",",
"\"output\":\"ignored\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "direct content wins");
assert!(!chunks[0].text.contains("[local_shell_call_output"));
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_c"));
}
#[test]
fn non_local_shell_call_output_type_does_not_trigger_prefix() {
let jsonl = concat!(
"{\"type\":\"message\",\"role\":\"assistant\",\"content\":\"hi\",",
"\"output\":\"ignored\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] hi");
assert!(!chunks[0].text.contains("[local_shell_call_output"));
}
#[test]
fn local_shell_call_output_in_message_envelope_is_extracted() {
let jsonl = concat!(
"{\"sessionId\":\"sess-1\",\"message\":{",
"\"type\":\"local_shell_call_output\",\"call_id\":\"call_env\",",
"\"output\":\"nested output\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[local_shell_call_output] nested output");
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_env"));
assert_eq!(chunks[0].session_id.as_deref(), Some("sess-1"));
}
#[test]
fn outer_tool_call_id_wins_over_local_shell_call_output_inner_call_id() {
let jsonl = concat!(
"{\"type\":\"local_shell_call_output\",",
"\"tool_call_id\":\"outer-call\",",
"\"call_id\":\"call_inner\",",
"\"output\":\"hi\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("outer-call"));
}
#[test]
fn function_call_output_line_renders_with_string_output() {
let jsonl = concat!(
"{\"type\":\"function_call_output\",\"id\":\"fco_abc\",",
"\"call_id\":\"call_xyz\",",
"\"output\":\"42 results found\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[function_call_output] 42 results found");
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_xyz"));
}
#[test]
fn function_call_output_line_renders_structured_output_deterministically() {
let jsonl = concat!(
"{\"type\":\"function_call_output\",\"call_id\":\"call_struct\",",
"\"output\":{\"status\":\"ok\",\"count\":3}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[function_call_output] {\"count\":3,\"status\":\"ok\"}"
);
}
#[test]
fn function_call_output_line_top_level_id_is_not_widened() {
let jsonl = concat!(
"{\"type\":\"function_call_output\",\"id\":\"fco_no_call\",",
"\"output\":\"hi\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert!(chunks[0].tool_call_id.is_none());
}
#[test]
fn function_call_output_line_missing_output_drops() {
let jsonl = concat!("{\"type\":\"function_call_output\",\"call_id\":\"call_x\"}\n");
assert!(extract_jsonl(jsonl).is_empty());
}
#[test]
fn function_call_output_line_blank_output_drops() {
for empty in [
"{\"type\":\"function_call_output\",\"call_id\":\"call_a\",\"output\":\"\"}\n",
"{\"type\":\"function_call_output\",\"call_id\":\"call_b\",\"output\":\" \"}\n",
"{\"type\":\"function_call_output\",\"call_id\":\"call_c\",\"output\":{}}\n",
"{\"type\":\"function_call_output\",\"call_id\":\"call_d\",\"output\":[]}\n",
] {
assert!(extract_jsonl(empty).is_empty(), "should drop: {empty:?}");
}
}
#[test]
fn function_call_output_line_existing_content_still_wins() {
let jsonl = concat!(
"{\"type\":\"function_call_output\",\"call_id\":\"call_c\",",
"\"content\":\"direct content wins\",",
"\"output\":\"ignored\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "direct content wins");
assert!(!chunks[0].text.contains("[function_call_output"));
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_c"));
}
#[test]
fn non_function_call_output_type_does_not_trigger_prefix() {
let jsonl = concat!(
"{\"type\":\"message\",\"role\":\"assistant\",\"content\":\"hi\",",
"\"output\":\"ignored\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] hi");
assert!(!chunks[0].text.contains("[function_call_output"));
}
#[test]
fn function_call_output_in_message_envelope_is_extracted() {
let jsonl = concat!(
"{\"sessionId\":\"sess-1\",\"message\":{",
"\"type\":\"function_call_output\",\"call_id\":\"call_env\",",
"\"output\":\"nested reply\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[function_call_output] nested reply");
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_env"));
assert_eq!(chunks[0].session_id.as_deref(), Some("sess-1"));
}
#[test]
fn outer_tool_call_id_wins_over_function_call_output_inner_call_id() {
let jsonl = concat!(
"{\"type\":\"function_call_output\",",
"\"tool_call_id\":\"outer-call\",",
"\"call_id\":\"call_inner\",",
"\"output\":\"hi\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("outer-call"));
}
#[test]
fn function_call_output_line_prefix_distinct_from_block() {
let jsonl = concat!(
"{\"type\":\"function_call_output\",\"call_id\":\"call_line\",",
"\"output\":\"line-form output\"}\n",
"{\"role\":\"tool\",\"content\":[",
"{\"type\":\"function_call_output\",\"call_id\":\"call_block\",",
"\"output\":\"block-form output\"}",
"]}\n",
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 2);
assert!(
chunks[0].text.starts_with("[function_call_output] "),
"top-level line should use distinct line prefix, got: {}",
chunks[0].text
);
assert!(
chunks[1].text.contains("[tool_result] block-form output"),
"content-block companion keeps existing [tool_result] prefix, got: {}",
chunks[1].text
);
}
#[test]
fn code_interpreter_call_output_line_renders_with_string_output() {
let jsonl = concat!(
"{\"type\":\"code_interpreter_call_output\",\"id\":\"cio_abc\",",
"\"call_id\":\"call_xyz\",",
"\"output\":\" shape: (3, 2)\\nDone.\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[code_interpreter_call_output] shape: (3, 2)\nDone."
);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_xyz"));
}
#[test]
fn code_interpreter_call_output_line_renders_structured_output_deterministically() {
let jsonl = concat!(
"{\"type\":\"code_interpreter_call_output\",\"call_id\":\"call_struct\",",
"\"output\":{\"status\":\"ok\",\"count\":3}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[code_interpreter_call_output] {\"count\":3,\"status\":\"ok\"}"
);
}
#[test]
fn code_interpreter_call_output_line_top_level_id_is_not_widened() {
let jsonl = concat!(
"{\"type\":\"code_interpreter_call_output\",\"id\":\"cio_no_call\",",
"\"output\":\"hi\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert!(chunks[0].tool_call_id.is_none());
}
#[test]
fn code_interpreter_call_output_line_missing_output_drops() {
let jsonl = concat!("{\"type\":\"code_interpreter_call_output\",\"call_id\":\"call_x\"}\n");
assert!(extract_jsonl(jsonl).is_empty());
}
#[test]
fn code_interpreter_call_output_line_blank_output_drops() {
for empty in [
"{\"type\":\"code_interpreter_call_output\",\"call_id\":\"call_a\",\"output\":\"\"}\n",
"{\"type\":\"code_interpreter_call_output\",\"call_id\":\"call_b\",\"output\":\" \"}\n",
"{\"type\":\"code_interpreter_call_output\",\"call_id\":\"call_c\",\"output\":{}}\n",
"{\"type\":\"code_interpreter_call_output\",\"call_id\":\"call_d\",\"output\":[]}\n",
] {
assert!(extract_jsonl(empty).is_empty(), "should drop: {empty:?}");
}
}
#[test]
fn code_interpreter_call_output_line_existing_content_still_wins() {
let jsonl = concat!(
"{\"type\":\"code_interpreter_call_output\",\"call_id\":\"call_c\",",
"\"content\":\"direct content wins\",",
"\"output\":\"ignored\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "direct content wins");
assert!(!chunks[0].text.contains("[code_interpreter_call_output"));
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_c"));
}
#[test]
fn non_code_interpreter_call_output_type_does_not_trigger_prefix() {
let jsonl = concat!(
"{\"type\":\"message\",\"role\":\"assistant\",\"content\":\"hi\",",
"\"output\":\"ignored\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] hi");
assert!(!chunks[0].text.contains("[code_interpreter_call_output"));
}
#[test]
fn code_interpreter_call_output_in_message_envelope_is_extracted() {
let jsonl = concat!(
"{\"sessionId\":\"sess-1\",\"message\":{",
"\"type\":\"code_interpreter_call_output\",\"call_id\":\"call_env\",",
"\"output\":\"nested reply\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[code_interpreter_call_output] nested reply"
);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_env"));
assert_eq!(chunks[0].session_id.as_deref(), Some("sess-1"));
}
#[test]
fn outer_tool_call_id_wins_over_code_interpreter_call_output_inner_call_id() {
let jsonl = concat!(
"{\"type\":\"code_interpreter_call_output\",",
"\"tool_call_id\":\"outer-call\",",
"\"call_id\":\"call_inner\",",
"\"output\":\"hi\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("outer-call"));
}
#[test]
fn custom_tool_call_output_line_renders_with_string_output() {
let jsonl = concat!(
"{\"type\":\"custom_tool_call_output\",\"id\":\"ctco_abc\",",
"\"call_id\":\"call_xyz\",",
"\"output\":\"42 results found\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[custom_tool_call_output] 42 results found");
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_xyz"));
}
#[test]
fn custom_tool_call_output_line_renders_structured_output_deterministically() {
let jsonl = concat!(
"{\"type\":\"custom_tool_call_output\",\"call_id\":\"call_struct\",",
"\"output\":{\"status\":\"ok\",\"count\":3}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[custom_tool_call_output] {\"count\":3,\"status\":\"ok\"}"
);
}
#[test]
fn custom_tool_call_output_line_top_level_id_is_not_widened() {
let jsonl = concat!(
"{\"type\":\"custom_tool_call_output\",\"id\":\"ctco_no_call\",",
"\"output\":\"hi\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert!(chunks[0].tool_call_id.is_none());
}
#[test]
fn custom_tool_call_output_line_missing_output_drops() {
let jsonl = concat!("{\"type\":\"custom_tool_call_output\",\"call_id\":\"call_x\"}\n");
assert!(extract_jsonl(jsonl).is_empty());
}
#[test]
fn custom_tool_call_output_line_blank_output_drops() {
for empty in [
"{\"type\":\"custom_tool_call_output\",\"call_id\":\"call_a\",\"output\":\"\"}\n",
"{\"type\":\"custom_tool_call_output\",\"call_id\":\"call_b\",\"output\":\" \"}\n",
"{\"type\":\"custom_tool_call_output\",\"call_id\":\"call_c\",\"output\":{}}\n",
"{\"type\":\"custom_tool_call_output\",\"call_id\":\"call_d\",\"output\":[]}\n",
] {
assert!(extract_jsonl(empty).is_empty(), "should drop: {empty:?}");
}
}
#[test]
fn custom_tool_call_output_line_existing_content_still_wins() {
let jsonl = concat!(
"{\"type\":\"custom_tool_call_output\",\"call_id\":\"call_c\",",
"\"content\":\"direct content wins\",",
"\"output\":\"ignored\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "direct content wins");
assert!(!chunks[0].text.contains("[custom_tool_call_output"));
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_c"));
}
#[test]
fn non_custom_tool_call_output_type_does_not_trigger_prefix() {
let jsonl = concat!(
"{\"type\":\"message\",\"role\":\"assistant\",\"content\":\"hi\",",
"\"output\":\"ignored\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] hi");
assert!(!chunks[0].text.contains("[custom_tool_call_output"));
}
#[test]
fn custom_tool_call_output_in_message_envelope_is_extracted() {
let jsonl = concat!(
"{\"sessionId\":\"sess-1\",\"message\":{",
"\"type\":\"custom_tool_call_output\",\"call_id\":\"call_env\",",
"\"output\":\"nested reply\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[custom_tool_call_output] nested reply");
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_env"));
assert_eq!(chunks[0].session_id.as_deref(), Some("sess-1"));
}
#[test]
fn outer_tool_call_id_wins_over_custom_tool_call_output_inner_call_id() {
let jsonl = concat!(
"{\"type\":\"custom_tool_call_output\",",
"\"tool_call_id\":\"outer-call\",",
"\"call_id\":\"call_inner\",",
"\"output\":\"hi\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("outer-call"));
}
#[test]
fn computer_call_line_renders_with_text_anchor() {
let jsonl = concat!(
"{\"type\":\"computer_call\",\"id\":\"cu_abc\",",
"\"call_id\":\"call_xyz\",\"status\":\"completed\",",
"\"action\":{\"type\":\"type\",\"text\":\"hello world\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[computer_call:type] {\"text\":\"hello world\"}"
);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_xyz"));
}
#[test]
fn computer_call_line_renders_with_keys_anchor() {
let jsonl = concat!(
"{\"type\":\"computer_call\",\"call_id\":\"call_keys\",",
"\"action\":{\"type\":\"keypress\",",
"\"keys\":[\"ctrl\",\"c\"]}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[computer_call:keypress] {\"keys\":[\"ctrl\",\"c\"]}"
);
}
#[test]
fn computer_call_line_text_and_keys_keep_sorted_keys() {
let jsonl = concat!(
"{\"type\":\"computer_call\",\"call_id\":\"call_both\",",
"\"action\":{\"type\":\"type\",",
"\"keys\":[\"shift\"],\"text\":\"A\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[computer_call:type] {\"keys\":[\"shift\"],\"text\":\"A\"}"
);
}
#[test]
fn computer_call_line_top_level_id_is_not_widened() {
let jsonl = concat!(
"{\"type\":\"computer_call\",\"id\":\"cu_no_call\",",
"\"action\":{\"type\":\"screenshot\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert!(chunks[0].tool_call_id.is_none());
}
#[test]
fn computer_call_line_drops_coordinates_button_and_safety_checks() {
let jsonl = concat!(
"{\"type\":\"computer_call\",\"call_id\":\"call_drop\",",
"\"action\":{\"type\":\"click\",\"x\":100,\"y\":200,",
"\"button\":\"NOISE_BUTTON\"},",
"\"pending_safety_checks\":[{\"id\":\"cs_1\",",
"\"code\":\"NOISE_SAFETY_CODE\",\"message\":\"NOISE_SAFETY_MSG\"}]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[computer_call:click]");
assert!(!chunks[0].text.contains("NOISE_BUTTON"));
assert!(!chunks[0].text.contains("NOISE_SAFETY_CODE"));
assert!(!chunks[0].text.contains("NOISE_SAFETY_MSG"));
assert!(!chunks[0].text.contains("100"));
assert!(!chunks[0].text.contains("200"));
}
#[test]
fn computer_call_line_missing_action_drops() {
let jsonl = "{\"type\":\"computer_call\",\"call_id\":\"call_x\"}\n";
assert!(extract_jsonl(jsonl).is_empty());
}
#[test]
fn computer_call_line_missing_action_type_drops() {
let jsonl = concat!(
"{\"type\":\"computer_call\",\"call_id\":\"call_x\",",
"\"action\":{\"text\":\"hi\"}}\n"
);
assert!(extract_jsonl(jsonl).is_empty());
}
#[test]
fn computer_call_line_screenshot_falls_back_to_bare_prefix() {
let jsonl = concat!(
"{\"type\":\"computer_call\",\"call_id\":\"call_ss\",",
"\"action\":{\"type\":\"screenshot\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[computer_call:screenshot]");
}
#[test]
fn computer_call_line_empty_keys_falls_back_to_bare_prefix() {
let empty = concat!(
"{\"type\":\"computer_call\",\"call_id\":\"call_e\",",
"\"action\":{\"type\":\"keypress\",\"keys\":[]}}\n"
);
let chunks = extract_jsonl(empty);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[computer_call:keypress]");
let all_blank = concat!(
"{\"type\":\"computer_call\",\"call_id\":\"call_b\",",
"\"action\":{\"type\":\"keypress\",\"keys\":[\"\",\" \"]}}\n"
);
let chunks = extract_jsonl(all_blank);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[computer_call:keypress]");
}
#[test]
fn computer_call_line_filters_non_string_keys_entries() {
let jsonl = concat!(
"{\"type\":\"computer_call\",\"call_id\":\"call_mix\",",
"\"action\":{\"type\":\"keypress\",",
"\"keys\":[\"ctrl\",42,null,{\"k\":\"v\"},\"c\",[1,2]]}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[computer_call:keypress] {\"keys\":[\"ctrl\",\"c\"]}"
);
}
#[test]
fn computer_call_line_existing_content_still_wins() {
let jsonl = concat!(
"{\"type\":\"computer_call\",\"call_id\":\"call_c\",",
"\"content\":\"direct content wins\",",
"\"action\":{\"type\":\"type\",\"text\":\"loser\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "direct content wins");
assert!(!chunks[0].text.contains("[computer_call"));
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_c"));
}
#[test]
fn non_computer_call_type_does_not_trigger_prefix() {
let jsonl = concat!(
"{\"type\":\"message\",\"role\":\"assistant\",\"content\":\"hi\",",
"\"action\":{\"type\":\"click\",\"x\":1,\"y\":2}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] hi");
assert!(!chunks[0].text.contains("[computer_call"));
}
#[test]
fn computer_call_in_message_envelope_is_extracted() {
let jsonl = concat!(
"{\"sessionId\":\"sess-1\",\"message\":{",
"\"type\":\"computer_call\",\"call_id\":\"call_env\",",
"\"action\":{\"type\":\"type\",\"text\":\"hi\"}}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[computer_call:type] {\"text\":\"hi\"}");
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_env"));
assert_eq!(chunks[0].session_id.as_deref(), Some("sess-1"));
}
#[test]
fn outer_tool_call_id_wins_over_computer_call_inner_call_id() {
let jsonl = concat!(
"{\"type\":\"computer_call\",\"tool_call_id\":\"outer-call\",",
"\"call_id\":\"call_inner\",",
"\"action\":{\"type\":\"type\",\"text\":\"hi\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("outer-call"));
}
#[test]
fn computer_call_output_line_renders_with_image_url_anchor() {
let jsonl = concat!(
"{\"type\":\"computer_call_output\",\"id\":\"cuo_item_1\",",
"\"call_id\":\"call_123\",\"status\":\"completed\",",
"\"output\":{\"type\":\"input_image\",",
"\"image_url\":\"https://example.test/screenshot.png\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[computer_call_output] https://example.test/screenshot.png"
);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_123"));
}
#[test]
fn computer_call_output_line_falls_back_to_file_id_anchor() {
let jsonl = concat!(
"{\"type\":\"computer_call_output\",\"id\":\"cuo_item_2\",",
"\"call_id\":\"call_124\",\"status\":\"completed\",",
"\"output\":{\"type\":\"input_image\",\"file_id\":\"file_abc\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[computer_call_output:file] file_abc");
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_124"));
}
#[test]
fn computer_call_output_line_image_url_wins_over_file_id() {
let jsonl = concat!(
"{\"type\":\"computer_call_output\",\"call_id\":\"call_both\",",
"\"output\":{\"type\":\"input_image\",",
"\"image_url\":\"https://example.test/win.png\",",
"\"file_id\":\"file_should_lose\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[computer_call_output] https://example.test/win.png"
);
assert!(!chunks[0].text.contains("file_should_lose"));
}
#[test]
fn computer_call_output_line_blank_image_url_falls_through_to_file_id() {
let jsonl = concat!(
"{\"type\":\"computer_call_output\",\"call_id\":\"call_blank\",",
"\"output\":{\"type\":\"input_image\",\"image_url\":\" \",",
"\"file_id\":\"file_fallback\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[computer_call_output:file] file_fallback");
}
#[test]
fn computer_call_output_line_missing_output_drops() {
let jsonl = "{\"type\":\"computer_call_output\",\"call_id\":\"call_x\"}\n";
assert!(extract_jsonl(jsonl).is_empty());
}
#[test]
fn computer_call_output_line_missing_anchors_drops() {
let jsonl = concat!(
"{\"type\":\"computer_call_output\",\"id\":\"cuo_item_3\",",
"\"call_id\":\"call_125\",\"status\":\"completed\",",
"\"output\":{\"type\":\"input_image\"}}\n"
);
assert!(extract_jsonl(jsonl).is_empty());
}
#[test]
fn computer_call_output_line_existing_content_still_wins() {
let jsonl = concat!(
"{\"type\":\"computer_call_output\",\"call_id\":\"call_c\",",
"\"content\":\"direct content wins\",",
"\"output\":{\"type\":\"input_image\",",
"\"image_url\":\"https://example.test/loser.png\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "direct content wins");
assert!(!chunks[0].text.contains("[computer_call_output"));
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_c"));
}
#[test]
fn computer_call_output_in_message_envelope_is_extracted() {
let jsonl = concat!(
"{\"sessionId\":\"sess-cco\",\"message\":{",
"\"type\":\"computer_call_output\",\"call_id\":\"call_env\",",
"\"output\":{\"type\":\"input_image\",",
"\"image_url\":\"https://example.test/env.png\"}}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[computer_call_output] https://example.test/env.png"
);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_env"));
assert_eq!(chunks[0].session_id.as_deref(), Some("sess-cco"));
}
#[test]
fn computer_call_output_line_top_level_id_is_not_widened() {
let jsonl = concat!(
"{\"type\":\"computer_call_output\",\"id\":\"cuo_no_call\",",
"\"output\":{\"type\":\"input_image\",",
"\"image_url\":\"https://example.test/x.png\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert!(chunks[0].tool_call_id.is_none());
}
#[test]
fn non_computer_call_output_type_does_not_trigger_prefix() {
let jsonl = concat!(
"{\"type\":\"message\",\"role\":\"assistant\",\"content\":\"hi\",",
"\"output\":{\"type\":\"input_image\",",
"\"image_url\":\"https://example.test/stray.png\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] hi");
assert!(!chunks[0].text.contains("[computer_call_output"));
}
#[test]
fn computer_call_output_line_with_data_url_surfaces_media_type_not_base64() {
let jsonl = concat!(
"{\"type\":\"computer_call_output\",\"id\":\"cuo_data\",",
"\"call_id\":\"call_data\",\"status\":\"completed\",",
"\"output\":{\"type\":\"input_image\",",
"\"image_url\":\"data:image/png;base64,iVBORw0KAAAAAAAOPAQUEPNGBYTES\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[computer_call_output:image/png]");
assert!(!chunks[0].text.contains("iVBORw0KAAAAAAAOPAQUEPNGBYTES"));
assert!(!chunks[0].text.contains("base64"));
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_data"));
}
#[test]
fn computer_call_output_line_with_malformed_data_url_falls_through_to_file_id() {
let jsonl = concat!(
"{\"type\":\"computer_call_output\",\"call_id\":\"call_mal\",",
"\"output\":{\"type\":\"input_image\",",
"\"image_url\":\"data:GARBAGENOSEMICOLON\",",
"\"file_id\":\"file_cco_fallback\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[computer_call_output:file] file_cco_fallback"
);
assert!(!chunks[0].text.contains("GARBAGENOSEMICOLON"));
}
#[test]
fn computer_call_output_line_with_blank_data_url_media_type_falls_through() {
let jsonl = concat!(
"{\"type\":\"computer_call_output\",\"call_id\":\"call_blank_mt\",",
"\"output\":{\"type\":\"input_image\",",
"\"image_url\":\"data: ;base64,AAAA\",",
"\"file_id\":\"file_cco_blank\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[computer_call_output:file] file_cco_blank");
}
#[test]
fn computer_call_output_line_data_url_without_file_id_drops() {
let jsonl = concat!(
"{\"type\":\"computer_call_output\",\"call_id\":\"call_orphan\",",
"\"output\":{\"type\":\"input_image\",",
"\"image_url\":\"data:malformed_no_semi\"}}\n"
);
assert!(extract_jsonl(jsonl).is_empty());
}
#[test]
fn computer_call_output_line_data_url_appends_current_url() {
let jsonl = concat!(
"{\"type\":\"computer_call_output\",\"call_id\":\"call_cu1\",",
"\"output\":{\"type\":\"computer_screenshot\",",
"\"image_url\":\"data:image/png;base64,OPAQUEBASE64ZZZ\",",
"\"current_url\":\"https://example.test/dashboard\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[computer_call_output:image/png] https://example.test/dashboard"
);
assert!(!chunks[0].text.contains("OPAQUEBASE64ZZZ"));
assert!(!chunks[0].text.contains("base64"));
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_cu1"));
}
#[test]
fn computer_call_output_line_https_image_url_appends_current_url() {
let jsonl = concat!(
"{\"type\":\"computer_call_output\",\"call_id\":\"call_cu2\",",
"\"output\":{\"type\":\"input_image\",",
"\"image_url\":\"https://cdn.example/shot.png\",",
"\"current_url\":\"https://example.test/page\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[computer_call_output] https://cdn.example/shot.png https://example.test/page"
);
}
#[test]
fn computer_call_output_line_file_id_anchor_appends_current_url() {
let jsonl = concat!(
"{\"type\":\"computer_call_output\",\"call_id\":\"call_cu3\",",
"\"output\":{\"type\":\"input_image\",\"file_id\":\"file_abc\",",
"\"current_url\":\"https://example.test/checkout\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[computer_call_output:file] file_abc https://example.test/checkout"
);
}
#[test]
fn computer_call_output_line_current_url_only_renders_anchor() {
let jsonl = concat!(
"{\"type\":\"computer_call_output\",\"call_id\":\"call_cu4\",",
"\"output\":{\"type\":\"computer_screenshot\",",
"\"current_url\":\"https://example.test/lonely\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[computer_call_output] https://example.test/lonely"
);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_cu4"));
}
#[test]
fn computer_call_output_line_blank_current_url_preserves_prior_behavior() {
let jsonl = concat!(
"{\"type\":\"computer_call_output\",\"call_id\":\"call_cu5\",",
"\"output\":{\"type\":\"computer_screenshot\",",
"\"image_url\":\"data:image/png;base64,X\",",
"\"current_url\":\" \"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[computer_call_output:image/png]");
assert_eq!(chunks[0].text.trim_end(), chunks[0].text);
}
#[test]
fn computer_call_output_line_malformed_data_url_with_current_url_still_renders() {
let jsonl = concat!(
"{\"type\":\"computer_call_output\",\"call_id\":\"call_cu6\",",
"\"output\":{\"type\":\"computer_screenshot\",",
"\"image_url\":\"data:GARBAGENOSEMI\",",
"\"file_id\":\"file_fallback\",",
"\"current_url\":\"https://example.test/recover\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[computer_call_output:file] file_fallback https://example.test/recover"
);
assert!(!chunks[0].text.contains("GARBAGENOSEMI"));
}
#[test]
fn reasoning_line_renders_with_summary_text_anchor() {
let jsonl = concat!(
"{\"type\":\"reasoning\",\"id\":\"rs_abc\",\"summary\":[",
"{\"type\":\"summary_text\",\"text\":\"Consider the tradeoffs.\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[reasoning] Consider the tradeoffs.");
}
#[test]
fn reasoning_line_joins_multiple_summary_text_blocks_in_order() {
let jsonl = concat!(
"{\"type\":\"reasoning\",\"summary\":[",
"{\"type\":\"summary_text\",\"text\":\"First step\"},",
"{\"type\":\"summary_text\",\"text\":\"Then second step\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[reasoning] First step\nThen second step");
}
#[test]
fn reasoning_line_filters_non_summary_text_blocks() {
let jsonl = concat!(
"{\"type\":\"reasoning\",\"summary\":[",
"{\"type\":\"summary_text\",\"text\":\"kept\"},",
"{\"type\":\"future_unknown\",\"text\":\"dropped\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[reasoning] kept");
assert!(!chunks[0].text.contains("dropped"));
}
#[test]
fn reasoning_line_skips_blank_summary_text_entries() {
let jsonl = concat!(
"{\"type\":\"reasoning\",\"summary\":[",
"{\"type\":\"summary_text\",\"text\":\" \"},",
"{\"type\":\"summary_text\"},",
"{\"type\":\"summary_text\",\"text\":\"only this survives\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[reasoning] only this survives");
}
#[test]
fn reasoning_line_missing_summary_drops() {
let jsonl = "{\"type\":\"reasoning\",\"id\":\"rs_no_summary\"}\n";
assert!(extract_jsonl(jsonl).is_empty());
}
#[test]
fn reasoning_line_empty_summary_drops() {
let jsonl = "{\"type\":\"reasoning\",\"summary\":[]}\n";
assert!(extract_jsonl(jsonl).is_empty());
}
#[test]
fn reasoning_line_all_blank_summary_text_drops() {
let jsonl = concat!(
"{\"type\":\"reasoning\",\"summary\":[",
"{\"type\":\"summary_text\",\"text\":\" \"},",
"{\"type\":\"future_unknown\",\"text\":\"ignored\"}",
"]}\n"
);
assert!(extract_jsonl(jsonl).is_empty());
}
#[test]
fn reasoning_line_never_serializes_encrypted_content() {
let jsonl = concat!(
"{\"type\":\"reasoning\",\"id\":\"rs_enc\",",
"\"encrypted_content\":\"OPAQUE_BASE64_BLOB_TOKEN\",",
"\"summary\":[",
"{\"type\":\"summary_text\",\"text\":\"plain summary\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[reasoning] plain summary");
assert!(!chunks[0].text.contains("OPAQUE_BASE64_BLOB_TOKEN"));
}
#[test]
fn reasoning_line_existing_content_still_wins() {
let jsonl = concat!(
"{\"type\":\"reasoning\",\"content\":\"direct content wins\",",
"\"summary\":[",
"{\"type\":\"summary_text\",\"text\":\"loser summary\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "direct content wins");
assert!(!chunks[0].text.contains("[reasoning]"));
assert!(!chunks[0].text.contains("loser summary"));
}
#[test]
fn reasoning_in_message_envelope_is_extracted() {
let jsonl = concat!(
"{\"sessionId\":\"sess-r1\",\"message\":{",
"\"type\":\"reasoning\",\"id\":\"rs_env\",\"summary\":[",
"{\"type\":\"summary_text\",\"text\":\"envelope summary\"}",
"]}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[reasoning] envelope summary");
assert_eq!(chunks[0].session_id.as_deref(), Some("sess-r1"));
}
#[test]
fn reasoning_line_top_level_id_is_not_widened() {
let jsonl = concat!(
"{\"type\":\"reasoning\",\"id\":\"rs_no_widen\",\"summary\":[",
"{\"type\":\"summary_text\",\"text\":\"some trace\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert!(chunks[0].tool_call_id.is_none());
}
#[test]
fn non_reasoning_type_does_not_trigger_prefix() {
let jsonl = concat!(
"{\"type\":\"message\",\"role\":\"assistant\",\"content\":\"hi\",",
"\"summary\":[",
"{\"type\":\"summary_text\",\"text\":\"stray summary\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] hi");
assert!(!chunks[0].text.contains("[reasoning]"));
assert!(!chunks[0].text.contains("stray summary"));
}
#[test]
fn image_generation_call_line_renders_with_revised_prompt_anchor() {
let jsonl = concat!(
"{\"type\":\"image_generation_call\",\"id\":\"ig_abc123\",",
"\"status\":\"completed\",",
"\"revised_prompt\":\"A red sailboat on a calm lake at sunset\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[image_generation_call] A red sailboat on a calm lake at sunset"
);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("ig_abc123"));
}
#[test]
fn image_generation_call_line_never_serializes_result_base64() {
let jsonl = concat!(
"{\"type\":\"image_generation_call\",\"id\":\"ig_drop\",",
"\"status\":\"completed\",",
"\"result\":\"iVBORw0KGgoAAAANSUhEUgAA_BIGBLOB_BYTES\",",
"\"revised_prompt\":\"a small dog\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[image_generation_call] a small dog");
assert!(!chunks[0].text.contains("iVBORw0KGgo"));
assert!(!chunks[0].text.contains("BIGBLOB"));
}
#[test]
fn image_generation_call_line_drops_status_and_config_fields() {
let jsonl = concat!(
"{\"type\":\"image_generation_call\",\"id\":\"ig_cfg\",",
"\"status\":\"completed\",\"size\":\"1024x1024\",",
"\"quality\":\"high\",\"output_format\":\"png\",",
"\"background\":\"auto\",",
"\"revised_prompt\":\"a tabby cat\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[image_generation_call] a tabby cat");
assert!(!chunks[0].text.contains("completed"));
assert!(!chunks[0].text.contains("1024x1024"));
assert!(!chunks[0].text.contains("\"high\""));
assert!(!chunks[0].text.contains("\"png\""));
assert!(!chunks[0].text.contains("\"auto\""));
}
#[test]
fn image_generation_call_line_missing_or_blank_revised_prompt_drops() {
let missing = concat!(
"{\"type\":\"image_generation_call\",\"id\":\"ig_missing\",",
"\"status\":\"completed\",\"result\":\"iVBOR\"}\n"
);
assert!(extract_jsonl(missing).is_empty());
let empty = concat!(
"{\"type\":\"image_generation_call\",\"id\":\"ig_empty\",",
"\"revised_prompt\":\"\"}\n"
);
assert!(extract_jsonl(empty).is_empty());
let blank = concat!(
"{\"type\":\"image_generation_call\",\"id\":\"ig_blank\",",
"\"revised_prompt\":\" \"}\n"
);
assert!(extract_jsonl(blank).is_empty());
}
#[test]
fn image_generation_call_line_existing_content_still_wins() {
let jsonl = concat!(
"{\"type\":\"image_generation_call\",\"id\":\"ig_content\",",
"\"content\":\"direct content wins\",",
"\"revised_prompt\":\"a red square\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "direct content wins");
assert!(!chunks[0].text.contains("[image_generation_call]"));
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("ig_content"));
}
#[test]
fn image_generation_call_line_id_widening_is_type_narrowed() {
let jsonl = concat!(
"{\"type\":\"message\",\"role\":\"user\",\"id\":\"msg_42\",",
"\"content\":\"hello\",\"revised_prompt\":\"ignored\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert!(chunks[0].tool_call_id.is_none());
}
#[test]
fn non_image_generation_call_type_does_not_trigger_prefix() {
let jsonl = concat!(
"{\"type\":\"message\",\"role\":\"assistant\",\"content\":\"hi\",",
"\"revised_prompt\":\"stray prompt\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] hi");
assert!(!chunks[0].text.contains("[image_generation_call]"));
assert!(!chunks[0].text.contains("stray prompt"));
}
#[test]
fn image_generation_call_in_message_envelope_is_extracted() {
let jsonl = concat!(
"{\"sessionId\":\"sess-1\",\"message\":{",
"\"type\":\"image_generation_call\",\"id\":\"ig_envelope\",",
"\"revised_prompt\":\"a yellow umbrella\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[image_generation_call] a yellow umbrella");
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("ig_envelope"));
assert_eq!(chunks[0].session_id.as_deref(), Some("sess-1"));
}
#[test]
fn outer_tool_call_id_wins_over_image_generation_call_line_id() {
let jsonl = concat!(
"{\"type\":\"image_generation_call\",\"id\":\"ig_inner\",",
"\"tool_call_id\":\"outer-call\",",
"\"revised_prompt\":\"a blue triangle\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("outer-call"));
}
#[test]
fn mcp_call_line_renders_with_server_and_name_prefix() {
let jsonl = concat!(
"{\"type\":\"mcp_call\",\"id\":\"mcp_abc123\",",
"\"server_label\":\"linear\",\"name\":\"create_issue\",",
"\"arguments\":\"{\\\"title\\\":\\\"file bug\\\"}\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[mcp_call:linear/create_issue] {\"title\":\"file bug\"}"
);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("mcp_abc123"));
assert_eq!(chunks[0].tool_name.as_deref(), Some("create_issue"));
}
#[test]
fn mcp_call_line_structured_arguments_serialize_deterministically() {
let jsonl = concat!(
"{\"type\":\"mcp_call\",\"id\":\"mcp_struct\",",
"\"server_label\":\"lantern\",\"name\":\"lantern_search\",",
"\"arguments\":{\"zebra\":1,\"alpha\":\"q\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[mcp_call:lantern/lantern_search] {\"alpha\":\"q\",\"zebra\":1}"
);
}
#[test]
fn mcp_call_line_falls_back_to_name_only_when_server_label_missing() {
let jsonl = concat!(
"{\"type\":\"mcp_call\",\"id\":\"mcp_no_server\",",
"\"name\":\"create_issue\",",
"\"arguments\":\"{}\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[mcp_call:create_issue] {}");
assert!(!chunks[0].text.contains('/'));
}
#[test]
fn mcp_call_line_blank_server_label_falls_back_to_name_only() {
let jsonl = concat!(
"{\"type\":\"mcp_call\",\"id\":\"mcp_blank_server\",",
"\"server_label\":\" \",\"name\":\"create_issue\",",
"\"arguments\":\"{}\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert!(chunks[0].text.starts_with("[mcp_call:create_issue]"));
}
#[test]
fn mcp_call_line_missing_or_blank_name_drops() {
let missing = concat!(
"{\"type\":\"mcp_call\",\"id\":\"mcp_no_name\",",
"\"server_label\":\"linear\",\"arguments\":\"{}\"}\n"
);
assert!(extract_jsonl(missing).is_empty());
let blank = concat!(
"{\"type\":\"mcp_call\",\"id\":\"mcp_blank_name\",",
"\"server_label\":\"linear\",\"name\":\" \",",
"\"arguments\":\"{}\"}\n"
);
assert!(extract_jsonl(blank).is_empty());
}
#[test]
fn mcp_call_line_empty_structured_arguments_collapses_to_prefix() {
let empty_obj = concat!(
"{\"type\":\"mcp_call\",\"id\":\"mcp_empty_obj\",",
"\"server_label\":\"linear\",\"name\":\"create_issue\",",
"\"arguments\":{}}\n"
);
let chunks = extract_jsonl(empty_obj);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[mcp_call:linear/create_issue]");
let empty_arr = concat!(
"{\"type\":\"mcp_call\",\"id\":\"mcp_empty_arr\",",
"\"server_label\":\"linear\",\"name\":\"create_issue\",",
"\"arguments\":[]}\n"
);
let chunks = extract_jsonl(empty_arr);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[mcp_call:linear/create_issue]");
}
#[test]
fn mcp_call_line_missing_arguments_collapses_to_prefix() {
let jsonl = concat!(
"{\"type\":\"mcp_call\",\"id\":\"mcp_no_args\",",
"\"server_label\":\"linear\",\"name\":\"create_issue\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[mcp_call:linear/create_issue]");
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("mcp_no_args"));
}
#[test]
fn mcp_call_line_existing_content_still_wins() {
let jsonl = concat!(
"{\"type\":\"mcp_call\",\"id\":\"mcp_content\",",
"\"server_label\":\"linear\",\"name\":\"create_issue\",",
"\"content\":\"direct content wins\",",
"\"arguments\":\"{}\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[tool:create_issue] direct content wins");
assert!(!chunks[0].text.contains("[mcp_call:"));
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("mcp_content"));
}
#[test]
fn mcp_call_line_arguments_payload_text_fallback_is_preempted() {
let jsonl = concat!(
"{\"type\":\"mcp_call\",\"id\":\"mcp_preempt\",",
"\"server_label\":\"linear\",\"name\":\"create_issue\",",
"\"arguments\":\"{\\\"q\\\":\\\"hello\\\"}\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert!(
chunks[0].text.starts_with("[mcp_call:linear/create_issue]"),
"mcp_call line must render behind the typed prefix, not the raw arguments fallback"
);
}
#[test]
fn mcp_call_line_id_widening_is_type_narrowed() {
let jsonl = concat!(
"{\"type\":\"message\",\"role\":\"user\",\"id\":\"msg_42\",",
"\"content\":\"hello\",\"server_label\":\"ignored\",",
"\"name\":\"ignored\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert!(chunks[0].tool_call_id.is_none());
}
#[test]
fn non_mcp_call_type_does_not_trigger_prefix() {
let jsonl = concat!(
"{\"type\":\"message\",\"role\":\"assistant\",\"content\":\"hi\",",
"\"server_label\":\"stray\",\"name\":\"stray-name\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert!(!chunks[0].text.contains("[mcp_call:"));
}
#[test]
fn mcp_call_in_message_envelope_is_extracted() {
let jsonl = concat!(
"{\"sessionId\":\"sess-1\",\"message\":{",
"\"type\":\"mcp_call\",\"id\":\"mcp_envelope\",",
"\"server_label\":\"linear\",\"name\":\"create_issue\",",
"\"arguments\":\"{\\\"q\\\":\\\"hello\\\"}\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[mcp_call:linear/create_issue] {\"q\":\"hello\"}"
);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("mcp_envelope"));
assert_eq!(chunks[0].session_id.as_deref(), Some("sess-1"));
}
#[test]
fn outer_tool_call_id_wins_over_mcp_call_line_id() {
let jsonl = concat!(
"{\"type\":\"mcp_call\",\"id\":\"mcp_inner\",",
"\"tool_call_id\":\"outer-call\",",
"\"server_label\":\"linear\",\"name\":\"create_issue\",",
"\"arguments\":\"{}\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("outer-call"));
}
#[test]
fn mcp_call_prefix_is_distinct_from_mcp_tool_use_block_prefix() {
let line = concat!(
"{\"type\":\"mcp_call\",\"id\":\"mcp_distinct\",",
"\"server_label\":\"linear\",\"name\":\"create_issue\",",
"\"arguments\":\"{}\"}\n"
);
let block = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"mcp_tool_use\",\"id\":\"mcptoolu_d\",",
"\"server_name\":\"linear\",\"name\":\"create_issue\",",
"\"input\":{}}]}\n"
);
let line_chunks = extract_jsonl(line);
let block_chunks = extract_jsonl(block);
assert_eq!(line_chunks.len(), 1);
assert_eq!(block_chunks.len(), 1);
assert!(
line_chunks[0]
.text
.starts_with("[mcp_call:linear/create_issue]")
);
assert!(
block_chunks[0]
.text
.contains("[mcp_tool_use:linear/create_issue]")
);
assert!(!line_chunks[0].text.contains("[mcp_tool_use:"));
assert!(!block_chunks[0].text.contains("[mcp_call:"));
}
#[test]
fn mcp_call_line_string_output_appended_on_separate_line() {
let jsonl = concat!(
"{\"type\":\"mcp_call\",\"id\":\"mcp_with_output\",",
"\"server_label\":\"linear\",\"name\":\"create_issue\",",
"\"arguments\":\"{\\\"title\\\":\\\"file bug\\\"}\",",
"\"output\":\"Issue LIN-123 created.\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[mcp_call:linear/create_issue] {\"title\":\"file bug\"}\n\
[mcp_call_output:linear/create_issue] Issue LIN-123 created."
);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("mcp_with_output"));
assert_eq!(chunks[0].tool_name.as_deref(), Some("create_issue"));
}
#[test]
fn mcp_call_line_structured_output_serializes_deterministically() {
let jsonl = concat!(
"{\"type\":\"mcp_call\",\"id\":\"mcp_struct_out\",",
"\"server_label\":\"lantern\",\"name\":\"lantern_search\",",
"\"arguments\":{},",
"\"output\":{\"zebra\":1,\"alpha\":\"hit\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[mcp_call:lantern/lantern_search]\n\
[mcp_call_output:lantern/lantern_search] {\"alpha\":\"hit\",\"zebra\":1}"
);
}
#[test]
fn mcp_call_line_string_error_appended_on_separate_line() {
let jsonl = concat!(
"{\"type\":\"mcp_call\",\"id\":\"mcp_with_error\",",
"\"server_label\":\"linear\",\"name\":\"create_issue\",",
"\"arguments\":\"{}\",",
"\"error\":\"Unauthorized: missing API token\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[mcp_call:linear/create_issue] {}\n\
[mcp_call_error:linear/create_issue] Unauthorized: missing API token"
);
}
#[test]
fn mcp_call_line_structured_error_object_serializes_deterministically() {
let jsonl = concat!(
"{\"type\":\"mcp_call\",\"id\":\"mcp_struct_err\",",
"\"server_label\":\"linear\",\"name\":\"create_issue\",",
"\"arguments\":\"{}\",",
"\"error\":{\"message\":\"forbidden\",\"code\":\"E_AUTH\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert!(
chunks[0].text.ends_with(
"[mcp_call_error:linear/create_issue] {\"code\":\"E_AUTH\",\"message\":\"forbidden\"}"
),
"structured error must serialize with BTreeMap-sorted keys; got: {}",
chunks[0].text
);
}
#[test]
fn mcp_call_line_missing_output_and_error_unchanged() {
let jsonl = concat!(
"{\"type\":\"mcp_call\",\"id\":\"mcp_no_out\",",
"\"server_label\":\"linear\",\"name\":\"create_issue\",",
"\"arguments\":\"{\\\"title\\\":\\\"file bug\\\"}\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[mcp_call:linear/create_issue] {\"title\":\"file bug\"}"
);
assert!(!chunks[0].text.contains("[mcp_call_output:"));
assert!(!chunks[0].text.contains("[mcp_call_error:"));
}
#[test]
fn mcp_call_line_null_or_empty_output_and_error_collapse() {
let cases = [
"\"output\":null,\"error\":null",
"\"output\":\"\",\"error\":\" \"",
"\"output\":{},\"error\":[]",
];
for fields in cases {
let jsonl = format!(
"{{\"type\":\"mcp_call\",\"id\":\"mcp_null\",\
\"server_label\":\"linear\",\"name\":\"create_issue\",\
\"arguments\":\"{{}}\",{fields}}}\n"
);
let chunks = extract_jsonl(&jsonl);
assert_eq!(chunks.len(), 1, "case {fields}");
assert_eq!(
chunks[0].text, "[mcp_call:linear/create_issue] {}",
"case {fields}: empty output/error must collapse to no extra line"
);
}
}
#[test]
fn mcp_call_line_both_output_and_error_render_in_order() {
let jsonl = concat!(
"{\"type\":\"mcp_call\",\"id\":\"mcp_both\",",
"\"server_label\":\"linear\",\"name\":\"create_issue\",",
"\"arguments\":\"{}\",",
"\"output\":\"Partial result\",",
"\"error\":\"Network timeout while fetching detail\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[mcp_call:linear/create_issue] {}\n\
[mcp_call_output:linear/create_issue] Partial result\n\
[mcp_call_error:linear/create_issue] Network timeout while fetching detail"
);
}
#[test]
fn mcp_call_line_output_label_matches_server_less_call() {
let jsonl = concat!(
"{\"type\":\"mcp_call\",\"id\":\"mcp_no_srv\",",
"\"name\":\"create_issue\",",
"\"arguments\":\"{}\",",
"\"output\":\"done\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[mcp_call:create_issue] {}\n[mcp_call_output:create_issue] done"
);
}
#[test]
fn mcp_call_line_approval_request_id_appended_after_call() {
let jsonl = concat!(
"{\"type\":\"mcp_call\",\"id\":\"mcp_gated_call\",",
"\"server_label\":\"linear\",\"name\":\"create_issue\",",
"\"arguments\":\"{\\\"title\\\":\\\"file bug\\\"}\",",
"\"approval_request_id\":\"mcpr_abc123\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[mcp_call:linear/create_issue] {\"title\":\"file bug\"}\n\
[mcp_call_approval_request:linear/create_issue] mcpr_abc123"
);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("mcp_gated_call"));
}
#[test]
fn mcp_call_line_approval_request_id_renders_before_output_and_error() {
let jsonl = concat!(
"{\"type\":\"mcp_call\",\"id\":\"mcp_gated_all\",",
"\"server_label\":\"linear\",\"name\":\"create_issue\",",
"\"arguments\":\"{}\",",
"\"approval_request_id\":\"mcpr_pair\",",
"\"output\":\"Issue created.\",",
"\"error\":\"Warning: assignee unset\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[mcp_call:linear/create_issue] {}\n\
[mcp_call_approval_request:linear/create_issue] mcpr_pair\n\
[mcp_call_output:linear/create_issue] Issue created.\n\
[mcp_call_error:linear/create_issue] Warning: assignee unset"
);
}
#[test]
fn mcp_call_line_missing_or_blank_approval_request_id_collapses() {
let cases = [
"",
",\"approval_request_id\":\"\"",
",\"approval_request_id\":\" \"",
",\"approval_request_id\":null",
];
for extra in cases {
let jsonl = format!(
"{{\"type\":\"mcp_call\",\"id\":\"mcp_no_appr\",\
\"server_label\":\"linear\",\"name\":\"create_issue\",\
\"arguments\":\"{{}}\"{extra}}}\n"
);
let chunks = extract_jsonl(&jsonl);
assert_eq!(chunks.len(), 1, "case {extra:?}");
assert_eq!(
chunks[0].text, "[mcp_call:linear/create_issue] {}",
"case {extra:?}: blank approval_request_id must collapse to no extra line"
);
assert!(
!chunks[0].text.contains("[mcp_call_approval_request:"),
"case {extra:?}: must not emit a bare approval-request line"
);
}
}
#[test]
fn mcp_call_line_approval_request_id_does_not_override_tool_call_id() {
let jsonl = concat!(
"{\"type\":\"mcp_call\",\"id\":\"mcp_canonical_id\",",
"\"server_label\":\"linear\",\"name\":\"create_issue\",",
"\"arguments\":\"{}\",",
"\"approval_request_id\":\"mcpr_should_not_override\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("mcp_canonical_id"));
assert!(
chunks[0].text.contains(
"[mcp_call_approval_request:linear/create_issue] mcpr_should_not_override"
)
);
}
#[test]
fn mcp_call_line_approval_request_id_server_less_label_parity() {
let jsonl = concat!(
"{\"type\":\"mcp_call\",\"id\":\"mcp_no_srv_appr\",",
"\"name\":\"create_issue\",",
"\"arguments\":\"{}\",",
"\"approval_request_id\":\"mcpr_xyz\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[mcp_call:create_issue] {}\n[mcp_call_approval_request:create_issue] mcpr_xyz"
);
}
#[test]
fn mcp_call_line_approval_request_id_is_type_narrowed() {
let jsonl = concat!(
"{\"type\":\"message\",\"role\":\"assistant\",\"content\":\"hello\",",
"\"approval_request_id\":\"mcpr_stray\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert!(!chunks[0].text.contains("[mcp_call_approval_request"));
assert!(!chunks[0].text.contains("mcpr_stray"));
}
#[test]
fn mcp_list_tools_line_renders_server_label_with_tool_names() {
let jsonl = concat!(
"{\"type\":\"mcp_list_tools\",\"id\":\"mcpl_abc\",",
"\"server_label\":\"linear\",",
"\"tools\":[",
"{\"name\":\"create_issue\",\"description\":\"Create a new issue\"},",
"{\"name\":\"search_issues\",\"description\":\"Search across issues\"},",
"{\"name\":\"update_issue\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[mcp_list_tools:linear] create_issue, search_issues, update_issue"
);
assert!(!chunks[0].text.contains("Create a new issue"));
assert!(!chunks[0].text.contains("Search across issues"));
}
#[test]
fn mcp_list_tools_line_falls_back_to_server_less_prefix_when_label_missing() {
let jsonl = concat!(
"{\"type\":\"mcp_list_tools\",\"id\":\"mcpl_noserver\",",
"\"tools\":[{\"name\":\"create_issue\"}]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[mcp_list_tools] create_issue");
assert!(!chunks[0].text.contains(':'));
}
#[test]
fn mcp_list_tools_line_blank_server_label_falls_back_to_server_less_prefix() {
let jsonl = concat!(
"{\"type\":\"mcp_list_tools\",\"id\":\"mcpl_blank\",",
"\"server_label\":\" \",",
"\"tools\":[{\"name\":\"create_issue\"}]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[mcp_list_tools] create_issue");
}
#[test]
fn mcp_list_tools_line_keeps_bare_prefix_when_tools_empty_but_server_present() {
let empty = concat!(
"{\"type\":\"mcp_list_tools\",\"id\":\"mcpl_empty\",",
"\"server_label\":\"linear\",\"tools\":[]}\n"
);
let chunks = extract_jsonl(empty);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[mcp_list_tools:linear]");
let missing = concat!(
"{\"type\":\"mcp_list_tools\",\"id\":\"mcpl_missing\",",
"\"server_label\":\"linear\"}\n"
);
let chunks = extract_jsonl(missing);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[mcp_list_tools:linear]");
let blank_names = concat!(
"{\"type\":\"mcp_list_tools\",\"id\":\"mcpl_blank_names\",",
"\"server_label\":\"linear\",",
"\"tools\":[{\"name\":\" \"},{\"name\":\"\"}]}\n"
);
let chunks = extract_jsonl(blank_names);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[mcp_list_tools:linear]");
}
#[test]
fn mcp_list_tools_line_drops_when_server_and_tools_both_absent() {
let jsonl = concat!(
"{\"type\":\"mcp_list_tools\",\"id\":\"mcpl_void\",",
"\"tools\":[]}\n"
);
assert!(extract_jsonl(jsonl).is_empty());
let jsonl_missing_tools = concat!("{\"type\":\"mcp_list_tools\",\"id\":\"mcpl_void2\"}\n");
assert!(extract_jsonl(jsonl_missing_tools).is_empty());
let jsonl_blank_only = concat!(
"{\"type\":\"mcp_list_tools\",\"id\":\"mcpl_void3\",",
"\"server_label\":\" \",\"tools\":[{\"name\":\"\"}]}\n"
);
assert!(extract_jsonl(jsonl_blank_only).is_empty());
}
#[test]
fn mcp_list_tools_line_filters_blank_and_non_string_names() {
let jsonl = concat!(
"{\"type\":\"mcp_list_tools\",\"id\":\"mcpl_mixed\",",
"\"server_label\":\"lantern\",",
"\"tools\":[",
"{\"name\":\"lantern_search\"},",
"{\"name\":\" \"},",
"{\"name\":42},",
"{\"name\":\"lantern_ingest\"},",
"{\"description\":\"orphan with no name\"},",
"{\"name\":\"lantern_show\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[mcp_list_tools:lantern] lantern_search, lantern_ingest, lantern_show"
);
}
#[test]
fn mcp_list_tools_line_top_level_id_is_not_promoted_to_tool_call_id() {
let jsonl = concat!(
"{\"type\":\"mcp_list_tools\",\"id\":\"mcpl_noidwiden\",",
"\"server_label\":\"linear\",",
"\"tools\":[{\"name\":\"create_issue\"}]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert!(chunks[0].tool_call_id.is_none());
}
#[test]
fn mcp_list_tools_line_existing_content_still_wins() {
let jsonl = concat!(
"{\"type\":\"mcp_list_tools\",\"id\":\"mcpl_content\",",
"\"server_label\":\"linear\",",
"\"content\":\"direct content wins\",",
"\"tools\":[{\"name\":\"create_issue\"}]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "direct content wins");
assert!(!chunks[0].text.contains("[mcp_list_tools"));
}
#[test]
fn mcp_list_tools_line_is_type_narrowed() {
let jsonl = concat!(
"{\"type\":\"message\",\"role\":\"assistant\",",
"\"content\":\"hi\",\"server_label\":\"stray\",",
"\"tools\":[{\"name\":\"stray-tool\"}]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert!(!chunks[0].text.contains("[mcp_list_tools"));
}
#[test]
fn mcp_list_tools_in_message_envelope_is_extracted() {
let jsonl = concat!(
"{\"sessionId\":\"sess-1\",\"message\":{",
"\"type\":\"mcp_list_tools\",\"id\":\"mcpl_env\",",
"\"server_label\":\"linear\",",
"\"tools\":[{\"name\":\"create_issue\"},{\"name\":\"search_issues\"}]}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[mcp_list_tools:linear] create_issue, search_issues"
);
assert_eq!(chunks[0].session_id.as_deref(), Some("sess-1"));
assert!(chunks[0].tool_call_id.is_none());
}
#[test]
fn mcp_list_tools_prefix_is_distinct_from_mcp_call_prefix() {
let list = concat!(
"{\"type\":\"mcp_list_tools\",\"id\":\"mcpl_distinct\",",
"\"server_label\":\"linear\",",
"\"tools\":[{\"name\":\"create_issue\"}]}\n"
);
let call = concat!(
"{\"type\":\"mcp_call\",\"id\":\"mcp_distinct\",",
"\"server_label\":\"linear\",\"name\":\"create_issue\",",
"\"arguments\":\"{}\"}\n"
);
let list_chunks = extract_jsonl(list);
let call_chunks = extract_jsonl(call);
assert_eq!(list_chunks.len(), 1);
assert_eq!(call_chunks.len(), 1);
assert!(list_chunks[0].text.starts_with("[mcp_list_tools:linear]"));
assert!(
call_chunks[0]
.text
.starts_with("[mcp_call:linear/create_issue]")
);
assert!(!list_chunks[0].text.contains("[mcp_call:"));
assert!(!call_chunks[0].text.contains("[mcp_list_tools"));
}
#[test]
fn mcp_list_tools_line_appends_error_when_listing_also_succeeds_partially() {
let jsonl = concat!(
"{\"type\":\"mcp_list_tools\",\"id\":\"mcpl_partial\",",
"\"server_label\":\"linear\",",
"\"tools\":[{\"name\":\"create_issue\"}],",
"\"error\":\"degraded: auth scope partially revoked\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[mcp_list_tools:linear] create_issue\n[mcp_list_tools_error:linear] degraded: auth scope partially revoked"
);
}
#[test]
fn mcp_list_tools_line_appends_error_to_bare_prefix_when_tools_absent_with_server_label() {
let jsonl = concat!(
"{\"type\":\"mcp_list_tools\",\"id\":\"mcpl_failed\",",
"\"server_label\":\"linear\",",
"\"error\":\"could not reach mcp server: connection refused\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[mcp_list_tools:linear]\n[mcp_list_tools_error:linear] could not reach mcp server: connection refused"
);
}
#[test]
fn mcp_list_tools_line_renders_error_alone_without_server_label() {
let jsonl = concat!(
"{\"type\":\"mcp_list_tools\",\"id\":\"mcpl_noservernoerr\",",
"\"error\":\"unknown server\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[mcp_list_tools_error] unknown server");
}
#[test]
fn mcp_list_tools_line_blank_error_preserves_existing_behavior() {
let blank = concat!(
"{\"type\":\"mcp_list_tools\",\"id\":\"mcpl_blankerr\",",
"\"server_label\":\"linear\",",
"\"tools\":[{\"name\":\"create_issue\"}],",
"\"error\":\" \"}\n"
);
let chunks = extract_jsonl(blank);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[mcp_list_tools:linear] create_issue");
assert!(!chunks[0].text.contains("[mcp_list_tools_error"));
let empty = concat!(
"{\"type\":\"mcp_list_tools\",\"id\":\"mcpl_emptyerr\",",
"\"server_label\":\"linear\",",
"\"tools\":[{\"name\":\"create_issue\"}],",
"\"error\":\"\"}\n"
);
let chunks = extract_jsonl(empty);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[mcp_list_tools:linear] create_issue");
let empty_obj = concat!(
"{\"type\":\"mcp_list_tools\",\"id\":\"mcpl_emptyobjerr\",",
"\"server_label\":\"linear\",",
"\"tools\":[{\"name\":\"create_issue\"}],",
"\"error\":{}}\n"
);
let chunks = extract_jsonl(empty_obj);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[mcp_list_tools:linear] create_issue");
let empty_arr = concat!(
"{\"type\":\"mcp_list_tools\",\"id\":\"mcpl_emptyarrerr\",",
"\"server_label\":\"linear\",",
"\"tools\":[{\"name\":\"create_issue\"}],",
"\"error\":[]}\n"
);
let chunks = extract_jsonl(empty_arr);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[mcp_list_tools:linear] create_issue");
}
#[test]
fn mcp_list_tools_line_structured_error_serializes_deterministically() {
let jsonl = concat!(
"{\"type\":\"mcp_list_tools\",\"id\":\"mcpl_structerr\",",
"\"server_label\":\"linear\",",
"\"error\":{\"reason\":\"auth_failed\",\"code\":401}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[mcp_list_tools:linear]\n[mcp_list_tools_error:linear] {\"code\":401,\"reason\":\"auth_failed\"}"
);
}
#[test]
fn mcp_list_tools_line_error_does_not_widen_top_level_id_to_tool_call_id() {
let jsonl = concat!(
"{\"type\":\"mcp_list_tools\",\"id\":\"mcpl_erridguard\",",
"\"server_label\":\"linear\",",
"\"error\":\"connection refused\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert!(chunks[0].tool_call_id.is_none());
}
#[test]
fn mcp_list_tools_error_prefix_is_distinct_from_listing_and_call_error() {
let listing_err = concat!(
"{\"type\":\"mcp_list_tools\",\"id\":\"mcpl_distinct_err\",",
"\"server_label\":\"linear\",",
"\"error\":\"boom\"}\n"
);
let call_err = concat!(
"{\"type\":\"mcp_call\",\"id\":\"mcp_distinct_err\",",
"\"server_label\":\"linear\",\"name\":\"create_issue\",",
"\"arguments\":\"{}\",\"error\":\"boom\"}\n"
);
let listing_chunks = extract_jsonl(listing_err);
let call_chunks = extract_jsonl(call_err);
assert_eq!(listing_chunks.len(), 1);
assert_eq!(call_chunks.len(), 1);
assert!(
listing_chunks[0]
.text
.contains("[mcp_list_tools_error:linear]")
);
assert!(!listing_chunks[0].text.contains("[mcp_call_error:"));
assert!(listing_chunks[0].text.contains("[mcp_list_tools:linear]"));
assert!(
call_chunks[0]
.text
.contains("[mcp_call_error:linear/create_issue]")
);
assert!(!call_chunks[0].text.contains("[mcp_list_tools_error"));
}
#[test]
fn function_call_line_renders_with_string_arguments_passthrough() {
let jsonl = concat!(
"{\"type\":\"function_call\",\"id\":\"fc_abc\",",
"\"call_id\":\"call_xyz\",\"name\":\"docs_search\",",
"\"arguments\":\"{\\\"q\\\":\\\"hello\\\"}\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[function_call:docs_search] {\"q\":\"hello\"}"
);
assert_eq!(chunks[0].tool_name.as_deref(), Some("docs_search"));
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_xyz"));
}
#[test]
fn function_call_line_structured_arguments_serialize_deterministically() {
let jsonl = concat!(
"{\"type\":\"function_call\",\"call_id\":\"call_struct\",",
"\"name\":\"search\",",
"\"arguments\":{\"zeta\":1,\"alpha\":2}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[function_call:search] {\"alpha\":2,\"zeta\":1}"
);
}
#[test]
fn function_call_line_top_level_id_is_not_widened() {
let jsonl = concat!(
"{\"type\":\"function_call\",\"id\":\"fc_no_call\",",
"\"name\":\"ping\",\"arguments\":\"{}\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert!(chunks[0].tool_call_id.is_none());
}
#[test]
fn function_call_line_missing_or_blank_name_drops() {
let missing = concat!(
"{\"type\":\"function_call\",\"call_id\":\"call_x\",",
"\"arguments\":\"{}\"}\n"
);
assert!(extract_jsonl(missing).is_empty());
let blank = concat!(
"{\"type\":\"function_call\",\"call_id\":\"call_x\",",
"\"name\":\" \",\"arguments\":\"{}\"}\n"
);
assert!(extract_jsonl(blank).is_empty());
}
#[test]
fn function_call_line_empty_structured_arguments_collapses_to_prefix() {
let empty_obj = concat!(
"{\"type\":\"function_call\",\"call_id\":\"call_a\",",
"\"name\":\"ping\",\"arguments\":{}}\n"
);
let chunks = extract_jsonl(empty_obj);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[function_call:ping]");
let empty_arr = concat!(
"{\"type\":\"function_call\",\"call_id\":\"call_b\",",
"\"name\":\"ping\",\"arguments\":[]}\n"
);
let chunks = extract_jsonl(empty_arr);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[function_call:ping]");
let string_braces = concat!(
"{\"type\":\"function_call\",\"call_id\":\"call_c\",",
"\"name\":\"ping\",\"arguments\":\"{}\"}\n"
);
let chunks = extract_jsonl(string_braces);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[function_call:ping] {}");
}
#[test]
fn function_call_line_missing_arguments_collapses_to_prefix() {
let jsonl = concat!(
"{\"type\":\"function_call\",\"call_id\":\"call_p\",",
"\"name\":\"ping\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[function_call:ping]");
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_p"));
assert_eq!(chunks[0].tool_name.as_deref(), Some("ping"));
}
#[test]
fn function_call_line_existing_content_still_wins() {
let jsonl = concat!(
"{\"type\":\"function_call\",\"call_id\":\"call_c\",",
"\"name\":\"docs_search\",",
"\"content\":\"direct content wins\",",
"\"arguments\":\"{}\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[tool:docs_search] direct content wins");
assert!(!chunks[0].text.contains("[function_call:"));
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_c"));
}
#[test]
fn function_call_line_arguments_payload_text_fallback_is_preempted() {
let jsonl = concat!(
"{\"type\":\"function_call\",\"call_id\":\"call_preempt\",",
"\"name\":\"docs_search\",",
"\"arguments\":\"{\\\"q\\\":\\\"hello\\\"}\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert!(
chunks[0].text.starts_with("[function_call:docs_search]"),
"function_call line must render behind the typed prefix, not the raw arguments fallback; got: {}",
chunks[0].text
);
assert!(!chunks[0].text.starts_with("[tool:docs_search]"));
}
#[test]
fn function_call_line_role_fold_does_not_duplicate_tool_prefix() {
let jsonl = concat!(
"{\"type\":\"function_call\",\"call_id\":\"call_nodup\",",
"\"name\":\"docs_search\",\"arguments\":\"{}\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[function_call:docs_search] {}");
assert!(!chunks[0].text.starts_with("[tool:"));
}
#[test]
fn non_function_call_type_does_not_trigger_prefix() {
let jsonl = concat!(
"{\"type\":\"message\",\"role\":\"assistant\",\"content\":\"hi\",",
"\"arguments\":\"{}\",\"name\":\"stray-name\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert!(!chunks[0].text.contains("[function_call:"));
}
#[test]
fn function_call_in_message_envelope_is_extracted() {
let jsonl = concat!(
"{\"sessionId\":\"sess-1\",\"message\":{",
"\"type\":\"function_call\",\"call_id\":\"call_env\",",
"\"name\":\"docs_search\",",
"\"arguments\":\"{\\\"q\\\":\\\"hello\\\"}\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[function_call:docs_search] {\"q\":\"hello\"}"
);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_env"));
assert_eq!(chunks[0].tool_name.as_deref(), Some("docs_search"));
assert_eq!(chunks[0].session_id.as_deref(), Some("sess-1"));
}
#[test]
fn outer_tool_call_id_wins_over_function_call_line_call_id() {
let jsonl = concat!(
"{\"type\":\"function_call\",",
"\"tool_call_id\":\"outer-call\",",
"\"call_id\":\"call_inner\",",
"\"name\":\"docs_search\",\"arguments\":\"{}\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("outer-call"));
}
#[test]
fn function_call_line_prefix_distinct_from_function_call_block() {
let jsonl = concat!(
"{\"type\":\"function_call\",\"call_id\":\"call_line\",",
"\"name\":\"docs_search\",",
"\"arguments\":\"{\\\"q\\\":\\\"line\\\"}\"}\n",
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"function_call\",\"call_id\":\"call_block\",",
"\"name\":\"docs_search\",",
"\"arguments\":\"{\\\"q\\\":\\\"block\\\"}\"}",
"]}\n",
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 2);
assert!(
chunks[0].text.starts_with("[function_call:docs_search] "),
"top-level line should use distinct line prefix, got: {}",
chunks[0].text
);
assert!(
chunks[1].text.contains("[tool_use:docs_search] "),
"content-block companion should keep `[tool_use:NAME]`, got: {}",
chunks[1].text
);
assert!(!chunks[0].text.contains("[tool_use:"));
assert!(!chunks[1].text.contains("[function_call:"));
}
#[test]
fn custom_tool_call_line_renders_with_string_input_passthrough() {
let jsonl = concat!(
"{\"type\":\"custom_tool_call\",\"id\":\"ctc_abc\",",
"\"call_id\":\"call_xyz\",\"name\":\"search_docs\",",
"\"input\":\"how do lanterns work\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[custom_tool_call:search_docs] how do lanterns work"
);
assert_eq!(chunks[0].tool_name.as_deref(), Some("search_docs"));
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_xyz"));
}
#[test]
fn custom_tool_call_line_structured_input_serializes_deterministically() {
let jsonl = concat!(
"{\"type\":\"custom_tool_call\",\"call_id\":\"call_struct\",",
"\"name\":\"search_docs\",",
"\"input\":{\"zeta\":1,\"alpha\":2}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[custom_tool_call:search_docs] {\"alpha\":2,\"zeta\":1}"
);
}
#[test]
fn custom_tool_call_line_missing_or_blank_name_drops() {
let missing = concat!(
"{\"type\":\"custom_tool_call\",\"call_id\":\"call_x\",",
"\"input\":\"q\"}\n"
);
assert!(extract_jsonl(missing).is_empty());
let blank = concat!(
"{\"type\":\"custom_tool_call\",\"call_id\":\"call_x\",",
"\"name\":\" \",\"input\":\"q\"}\n"
);
assert!(extract_jsonl(blank).is_empty());
}
#[test]
fn custom_tool_call_line_empty_or_missing_input_collapses_to_prefix() {
let missing = concat!(
"{\"type\":\"custom_tool_call\",\"call_id\":\"call_a\",",
"\"name\":\"search_docs\"}\n"
);
let chunks = extract_jsonl(missing);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[custom_tool_call:search_docs]");
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_a"));
assert_eq!(chunks[0].tool_name.as_deref(), Some("search_docs"));
let empty_obj = concat!(
"{\"type\":\"custom_tool_call\",\"call_id\":\"call_b\",",
"\"name\":\"search_docs\",\"input\":{}}\n"
);
let chunks = extract_jsonl(empty_obj);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[custom_tool_call:search_docs]");
let empty_arr = concat!(
"{\"type\":\"custom_tool_call\",\"call_id\":\"call_c\",",
"\"name\":\"search_docs\",\"input\":[]}\n"
);
let chunks = extract_jsonl(empty_arr);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[custom_tool_call:search_docs]");
}
#[test]
fn custom_tool_call_line_existing_content_still_wins() {
let jsonl = concat!(
"{\"type\":\"custom_tool_call\",\"call_id\":\"call_c\",",
"\"name\":\"search_docs\",",
"\"content\":\"direct content wins\",",
"\"input\":\"q\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[tool:search_docs] direct content wins");
assert!(!chunks[0].text.contains("[custom_tool_call:"));
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_c"));
}
#[test]
fn custom_tool_call_in_message_envelope_is_extracted() {
let jsonl = concat!(
"{\"sessionId\":\"sess-1\",\"message\":{",
"\"type\":\"custom_tool_call\",\"call_id\":\"call_env\",",
"\"name\":\"search_docs\",",
"\"input\":\"how do lanterns work\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[custom_tool_call:search_docs] how do lanterns work"
);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_env"));
assert_eq!(chunks[0].tool_name.as_deref(), Some("search_docs"));
assert_eq!(chunks[0].session_id.as_deref(), Some("sess-1"));
}
#[test]
fn custom_tool_call_line_top_level_id_is_not_widened() {
let jsonl = concat!(
"{\"type\":\"custom_tool_call\",\"id\":\"ctc_no_call\",",
"\"name\":\"search_docs\",\"input\":\"q\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert!(chunks[0].tool_call_id.is_none());
}
#[test]
fn custom_tool_call_line_role_fold_does_not_duplicate_tool_prefix() {
let jsonl = concat!(
"{\"type\":\"custom_tool_call\",\"call_id\":\"call_nodup\",",
"\"name\":\"search_docs\",\"input\":\"q\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[custom_tool_call:search_docs] q");
assert!(!chunks[0].text.starts_with("[tool:"));
}
#[test]
fn mcp_approval_request_line_renders_with_server_and_name_prefix() {
let jsonl = concat!(
"{\"type\":\"mcp_approval_request\",\"id\":\"mcpr_abc123\",",
"\"server_label\":\"deepwiki\",\"name\":\"ask_question\",",
"\"arguments\":\"{\\\"question\\\":\\\"hello\\\"}\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[mcp_approval_request:deepwiki/ask_question] {\"question\":\"hello\"}"
);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("mcpr_abc123"));
assert_eq!(chunks[0].tool_name.as_deref(), Some("ask_question"));
}
#[test]
fn mcp_approval_request_line_structured_arguments_serialize_deterministically() {
let jsonl = concat!(
"{\"type\":\"mcp_approval_request\",\"id\":\"mcpr_struct\",",
"\"server_label\":\"lantern\",\"name\":\"lantern_forget\",",
"\"arguments\":{\"zebra\":1,\"alpha\":\"q\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[mcp_approval_request:lantern/lantern_forget] {\"alpha\":\"q\",\"zebra\":1}"
);
}
#[test]
fn mcp_approval_request_line_falls_back_to_name_only_when_server_label_missing() {
let missing = concat!(
"{\"type\":\"mcp_approval_request\",\"id\":\"mcpr_no_server\",",
"\"name\":\"ask_question\",\"arguments\":\"{}\"}\n"
);
let chunks = extract_jsonl(missing);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[mcp_approval_request:ask_question] {}");
assert!(!chunks[0].text.contains('/'));
let blank = concat!(
"{\"type\":\"mcp_approval_request\",\"id\":\"mcpr_blank_server\",",
"\"server_label\":\" \",\"name\":\"ask_question\",",
"\"arguments\":\"{}\"}\n"
);
let chunks = extract_jsonl(blank);
assert_eq!(chunks.len(), 1);
assert!(
chunks[0]
.text
.starts_with("[mcp_approval_request:ask_question]")
);
}
#[test]
fn mcp_approval_request_line_missing_or_blank_name_drops() {
let missing = concat!(
"{\"type\":\"mcp_approval_request\",\"id\":\"mcpr_no_name\",",
"\"server_label\":\"deepwiki\",\"arguments\":\"{}\"}\n"
);
assert!(extract_jsonl(missing).is_empty());
let blank = concat!(
"{\"type\":\"mcp_approval_request\",\"id\":\"mcpr_blank_name\",",
"\"server_label\":\"deepwiki\",\"name\":\" \",",
"\"arguments\":\"{}\"}\n"
);
assert!(extract_jsonl(blank).is_empty());
}
#[test]
fn mcp_approval_request_line_empty_structured_arguments_collapses_to_prefix() {
let empty_obj = concat!(
"{\"type\":\"mcp_approval_request\",\"id\":\"mcpr_empty_obj\",",
"\"server_label\":\"deepwiki\",\"name\":\"ask_question\",",
"\"arguments\":{}}\n"
);
let chunks = extract_jsonl(empty_obj);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[mcp_approval_request:deepwiki/ask_question]"
);
let empty_arr = concat!(
"{\"type\":\"mcp_approval_request\",\"id\":\"mcpr_empty_arr\",",
"\"server_label\":\"deepwiki\",\"name\":\"ask_question\",",
"\"arguments\":[]}\n"
);
let chunks = extract_jsonl(empty_arr);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[mcp_approval_request:deepwiki/ask_question]"
);
}
#[test]
fn mcp_approval_request_line_missing_arguments_collapses_to_prefix() {
let jsonl = concat!(
"{\"type\":\"mcp_approval_request\",\"id\":\"mcpr_no_args\",",
"\"server_label\":\"deepwiki\",\"name\":\"ask_question\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[mcp_approval_request:deepwiki/ask_question]"
);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("mcpr_no_args"));
}
#[test]
fn mcp_approval_request_line_arguments_payload_text_fallback_is_preempted() {
let jsonl = concat!(
"{\"type\":\"mcp_approval_request\",\"id\":\"mcpr_preempt\",",
"\"server_label\":\"deepwiki\",\"name\":\"ask_question\",",
"\"arguments\":\"{\\\"q\\\":\\\"hello\\\"}\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert!(
chunks[0]
.text
.starts_with("[mcp_approval_request:deepwiki/ask_question]"),
"mcp_approval_request line must render behind the typed prefix, \
not the raw arguments fallback"
);
}
#[test]
fn mcp_approval_request_line_existing_content_still_wins() {
let jsonl = concat!(
"{\"type\":\"mcp_approval_request\",\"id\":\"mcpr_content\",",
"\"server_label\":\"deepwiki\",\"name\":\"ask_question\",",
"\"content\":\"direct content wins\",",
"\"arguments\":\"{}\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[tool:ask_question] direct content wins");
assert!(!chunks[0].text.contains("[mcp_approval_request:"));
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("mcpr_content"));
}
#[test]
fn mcp_approval_request_line_id_widening_is_type_narrowed() {
let jsonl = concat!(
"{\"type\":\"message\",\"role\":\"user\",\"id\":\"msg_42\",",
"\"content\":\"hello\",\"server_label\":\"deepwiki\",",
"\"name\":\"ignored\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert!(chunks[0].tool_call_id.is_none());
}
#[test]
fn non_mcp_approval_request_type_does_not_trigger_prefix() {
let jsonl = concat!(
"{\"type\":\"message\",\"role\":\"assistant\",\"content\":\"hi\",",
"\"server_label\":\"stray\",\"name\":\"stray-name\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert!(!chunks[0].text.contains("[mcp_approval_request:"));
}
#[test]
fn mcp_approval_request_in_message_envelope_is_extracted() {
let jsonl = concat!(
"{\"sessionId\":\"sess-1\",\"message\":{",
"\"type\":\"mcp_approval_request\",\"id\":\"mcpr_envelope\",",
"\"server_label\":\"deepwiki\",\"name\":\"ask_question\",",
"\"arguments\":\"{\\\"q\\\":\\\"hello\\\"}\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[mcp_approval_request:deepwiki/ask_question] {\"q\":\"hello\"}"
);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("mcpr_envelope"));
assert_eq!(chunks[0].session_id.as_deref(), Some("sess-1"));
}
#[test]
fn outer_tool_call_id_wins_over_mcp_approval_request_line_id() {
let jsonl = concat!(
"{\"type\":\"mcp_approval_request\",\"id\":\"mcpr_inner\",",
"\"tool_call_id\":\"outer-call\",",
"\"server_label\":\"deepwiki\",\"name\":\"ask_question\",",
"\"arguments\":\"{}\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("outer-call"));
}
#[test]
fn mcp_approval_request_prefix_is_distinct_from_mcp_call_line_prefix() {
let approval = concat!(
"{\"type\":\"mcp_approval_request\",\"id\":\"mcpr_pair\",",
"\"server_label\":\"deepwiki\",\"name\":\"ask_question\",",
"\"arguments\":\"{}\"}\n"
);
let call = concat!(
"{\"type\":\"mcp_call\",\"id\":\"mcp_pair\",",
"\"server_label\":\"deepwiki\",\"name\":\"ask_question\",",
"\"arguments\":\"{}\"}\n"
);
let approval_chunks = extract_jsonl(approval);
let call_chunks = extract_jsonl(call);
assert_eq!(approval_chunks.len(), 1);
assert_eq!(call_chunks.len(), 1);
assert!(
approval_chunks[0]
.text
.starts_with("[mcp_approval_request:deepwiki/ask_question]")
);
assert!(
call_chunks[0]
.text
.starts_with("[mcp_call:deepwiki/ask_question]")
);
assert!(!approval_chunks[0].text.contains("[mcp_call:"));
assert!(!call_chunks[0].text.contains("[mcp_approval_request:"));
}
#[test]
fn mcp_approval_response_line_renders_approved_prefix() {
let jsonl = concat!(
"{\"type\":\"mcp_approval_response\",",
"\"approval_request_id\":\"mcpr_abc123\",",
"\"approve\":true}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[mcp_approval_response:approved]");
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("mcpr_abc123"));
}
#[test]
fn mcp_approval_response_line_renders_denied_prefix() {
let jsonl = concat!(
"{\"type\":\"mcp_approval_response\",",
"\"approval_request_id\":\"mcpr_xyz\",",
"\"approve\":false}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[mcp_approval_response:denied]");
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("mcpr_xyz"));
}
#[test]
fn mcp_approval_response_line_appends_reason_when_present() {
let jsonl = concat!(
"{\"type\":\"mcp_approval_response\",",
"\"approval_request_id\":\"mcpr_pair\",",
"\"approve\":false,",
"\"reason\":\"policy: never approve writes\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[mcp_approval_response:denied] policy: never approve writes"
);
}
#[test]
fn mcp_approval_response_line_blank_reason_collapses_to_prefix() {
let blank = concat!(
"{\"type\":\"mcp_approval_response\",",
"\"approval_request_id\":\"mcpr_pair\",",
"\"approve\":true,\"reason\":\"\"}\n"
);
let chunks = extract_jsonl(blank);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[mcp_approval_response:approved]");
let whitespace = concat!(
"{\"type\":\"mcp_approval_response\",",
"\"approval_request_id\":\"mcpr_pair\",",
"\"approve\":true,\"reason\":\" \"}\n"
);
let chunks = extract_jsonl(whitespace);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[mcp_approval_response:approved]");
}
#[test]
fn mcp_approval_response_line_missing_approval_request_id_drops() {
let missing = "{\"type\":\"mcp_approval_response\",\"approve\":true}\n";
let chunks = extract_jsonl(missing);
assert!(chunks.is_empty());
let blank = concat!(
"{\"type\":\"mcp_approval_response\",",
"\"approval_request_id\":\" \",\"approve\":true}\n"
);
let chunks = extract_jsonl(blank);
assert!(chunks.is_empty());
}
#[test]
fn mcp_approval_response_line_missing_or_non_bool_approve_drops() {
let missing = concat!(
"{\"type\":\"mcp_approval_response\",",
"\"approval_request_id\":\"mcpr_x\"}\n"
);
let chunks = extract_jsonl(missing);
assert!(chunks.is_empty());
let stringy = concat!(
"{\"type\":\"mcp_approval_response\",",
"\"approval_request_id\":\"mcpr_x\",",
"\"approve\":\"true\"}\n"
);
let chunks = extract_jsonl(stringy);
assert!(chunks.is_empty());
}
#[test]
fn non_mcp_approval_response_type_does_not_trigger_prefix() {
let jsonl = concat!(
"{\"type\":\"message\",\"content\":\"hello\",",
"\"approval_request_id\":\"mcpr_stray\",",
"\"approve\":true}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert!(!chunks[0].text.contains("[mcp_approval_response:"));
}
#[test]
fn mcp_approval_response_existing_content_still_wins() {
let jsonl = concat!(
"{\"type\":\"mcp_approval_response\",",
"\"approval_request_id\":\"mcpr_pair\",",
"\"approve\":true,\"content\":\"explicit\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "explicit");
assert!(!chunks[0].text.contains("[mcp_approval_response:"));
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("mcpr_pair"));
}
#[test]
fn mcp_approval_response_in_message_envelope_is_extracted() {
let jsonl = concat!(
"{\"sessionId\":\"sess-1\",\"message\":{",
"\"type\":\"mcp_approval_response\",",
"\"approval_request_id\":\"mcpr_envelope\",",
"\"approve\":true,\"reason\":\"ok\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[mcp_approval_response:approved] ok");
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("mcpr_envelope"));
assert_eq!(chunks[0].session_id.as_deref(), Some("sess-1"));
}
#[test]
fn outer_tool_call_id_wins_over_mcp_approval_response_widening() {
let jsonl = concat!(
"{\"type\":\"mcp_approval_response\",",
"\"tool_call_id\":\"outer-call\",",
"\"approval_request_id\":\"mcpr_inner\",",
"\"approve\":true}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("outer-call"));
}
#[test]
fn mcp_approval_request_and_response_join_by_tool_call_id() {
let request = concat!(
"{\"type\":\"mcp_approval_request\",\"id\":\"mcpr_pair\",",
"\"server_label\":\"deepwiki\",\"name\":\"ask_question\",",
"\"arguments\":\"{}\"}\n"
);
let response = concat!(
"{\"type\":\"mcp_approval_response\",",
"\"approval_request_id\":\"mcpr_pair\",",
"\"approve\":true}\n"
);
let req_chunks = extract_jsonl(request);
let resp_chunks = extract_jsonl(response);
assert_eq!(req_chunks.len(), 1);
assert_eq!(resp_chunks.len(), 1);
assert_eq!(req_chunks[0].tool_call_id, resp_chunks[0].tool_call_id);
assert_eq!(req_chunks[0].tool_call_id.as_deref(), Some("mcpr_pair"));
}
#[test]
fn mcp_approval_response_prefix_is_distinct_from_request_prefix() {
let request = concat!(
"{\"type\":\"mcp_approval_request\",\"id\":\"mcpr_pair\",",
"\"server_label\":\"deepwiki\",\"name\":\"ask_question\",",
"\"arguments\":\"{}\"}\n"
);
let response = concat!(
"{\"type\":\"mcp_approval_response\",",
"\"approval_request_id\":\"mcpr_pair\",",
"\"approve\":true}\n"
);
let req_chunks = extract_jsonl(request);
let resp_chunks = extract_jsonl(response);
assert!(
req_chunks[0]
.text
.starts_with("[mcp_approval_request:deepwiki/ask_question]")
);
assert!(
resp_chunks[0]
.text
.starts_with("[mcp_approval_response:approved]")
);
assert!(!req_chunks[0].text.contains("[mcp_approval_response:"));
assert!(!resp_chunks[0].text.contains("[mcp_approval_request:"));
}
#[test]
fn legacy_function_call_field_renders_as_tool_use_prefix() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":null,",
"\"function_call\":{\"name\":\"get_weather\",",
"\"arguments\":\"{\\\"location\\\":\\\"NYC\\\"}\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [tool_use:get_weather] {\"location\":\"NYC\"}"
);
assert_eq!(chunks[0].role.as_deref(), Some("assistant"));
assert_eq!(chunks[0].tool_name.as_deref(), Some("get_weather"));
assert_eq!(chunks[0].tool_call_id.as_deref(), None);
}
#[test]
fn legacy_function_call_field_with_structured_arguments_is_deterministic() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":null,",
"\"function_call\":{\"name\":\"search\",",
"\"arguments\":{\"limit\":10,\"q\":\"rust\"}}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [tool_use:search] {\"limit\":10,\"q\":\"rust\"}"
);
assert_eq!(chunks[0].tool_name.as_deref(), Some("search"));
}
#[test]
fn legacy_function_call_field_missing_arguments_renders_bare_prefix() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":null,",
"\"function_call\":{\"name\":\"ping\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] [tool_use:ping]");
assert_eq!(chunks[0].tool_name.as_deref(), Some("ping"));
}
#[test]
fn legacy_function_call_field_empty_arguments_renders_bare_prefix() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":null,",
"\"function_call\":{\"name\":\"ping\",\"arguments\":{}}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] [tool_use:ping]");
}
#[test]
fn legacy_function_call_field_missing_name_drops_line() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":null,",
"\"function_call\":{\"arguments\":\"{}\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert!(chunks.is_empty());
}
#[test]
fn legacy_function_call_field_blank_name_drops_line() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":null,",
"\"function_call\":{\"name\":\" \",\"arguments\":\"{}\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert!(chunks.is_empty());
}
#[test]
fn content_wins_over_legacy_function_call_field() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":\"explanation prose\",",
"\"function_call\":{\"name\":\"get_weather\",",
"\"arguments\":\"{}\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] explanation prose");
assert!(!chunks[0].text.contains("[tool_use:"));
assert_eq!(chunks[0].tool_name.as_deref(), Some("get_weather"));
}
#[test]
fn legacy_function_call_field_in_message_envelope_is_extracted() {
let jsonl = concat!(
"{\"type\":\"assistant\",\"sessionId\":\"sess-1\",",
"\"message\":{\"role\":\"assistant\",\"content\":null,",
"\"function_call\":{\"name\":\"get_weather\",",
"\"arguments\":\"{\\\"location\\\":\\\"NYC\\\"}\"}}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert!(
chunks[0]
.text
.contains("[tool_use:get_weather] {\"location\":\"NYC\"}")
);
assert_eq!(chunks[0].session_id.as_deref(), Some("sess-1"));
assert_eq!(chunks[0].tool_name.as_deref(), Some("get_weather"));
}
#[test]
fn tool_calls_array_still_wins_over_legacy_function_call_field() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":null,",
"\"tool_calls\":[{\"id\":\"call_1\",\"type\":\"function\",",
"\"function\":{\"name\":\"modern_call\",\"arguments\":\"{}\"}}],",
"\"function_call\":{\"name\":\"legacy_call\",\"arguments\":\"{}\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert!(chunks[0].text.contains("[tool_use:modern_call]"));
assert!(!chunks[0].text.contains("[tool_use:legacy_call]"));
assert_eq!(chunks[0].tool_call_id.as_deref(), Some("call_1"));
assert_eq!(chunks[0].tool_name.as_deref(), Some("modern_call"));
}
#[test]
fn non_function_call_object_field_does_not_trigger_legacy_path() {
let jsonl = concat!(
"{\"role\":\"user\",\"content\":\"hi\",",
"\"function_call\":{\"name\":\"unused\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[user] hi");
assert_eq!(chunks[0].tool_name.as_deref(), Some("unused"));
}
#[test]
fn legacy_assistant_audio_field_renders_transcript_anchor() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":null,",
"\"audio\":{\"id\":\"audio_abc\",",
"\"data\":\"BASE64_PAYLOAD_NEVER_LEAKS\",",
"\"transcript\":\"hello there\",",
"\"expires_at\":1700000000}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] [audio] hello there");
assert_eq!(chunks[0].role.as_deref(), Some("assistant"));
assert!(!chunks[0].text.contains("BASE64_PAYLOAD_NEVER_LEAKS"));
assert!(!chunks[0].text.contains("audio_abc"));
assert!(!chunks[0].text.contains("1700000000"));
assert_eq!(chunks[0].tool_call_id.as_deref(), None);
}
#[test]
fn legacy_assistant_audio_field_missing_transcript_drops_line() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":null,",
"\"audio\":{\"id\":\"audio_abc\",",
"\"data\":\"BASE64_PAYLOAD\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert!(chunks.is_empty());
}
#[test]
fn legacy_assistant_audio_field_blank_transcript_drops_line() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":null,",
"\"audio\":{\"transcript\":\" \"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert!(chunks.is_empty());
}
#[test]
fn legacy_assistant_audio_field_non_object_audio_drops_line() {
let jsonl = "{\"role\":\"assistant\",\"content\":null,\"audio\":\"not an object\"}\n";
let chunks = extract_jsonl(jsonl);
assert!(chunks.is_empty());
}
#[test]
fn content_wins_over_legacy_assistant_audio_field() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":\"prose transcript\",",
"\"audio\":{\"transcript\":\"audio transcript\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] prose transcript");
assert!(!chunks[0].text.contains("[audio]"));
}
#[test]
fn legacy_assistant_audio_field_in_message_envelope_is_extracted() {
let jsonl = concat!(
"{\"type\":\"assistant\",\"sessionId\":\"sess-audio\",",
"\"message\":{\"role\":\"assistant\",\"content\":null,",
"\"audio\":{\"transcript\":\"nested hello\",",
"\"data\":\"BASE64\"}}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert!(chunks[0].text.contains("[audio] nested hello"));
assert!(!chunks[0].text.contains("BASE64"));
assert_eq!(chunks[0].session_id.as_deref(), Some("sess-audio"));
}
#[test]
fn legacy_assistant_audio_prefix_distinct_from_content_block_audio() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":null,",
"\"audio\":{\"transcript\":\"flat shape reply\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert!(chunks[0].text.contains("[audio] flat shape reply"));
assert!(!chunks[0].text.contains("[input_audio]"));
assert!(!chunks[0].text.contains("[output_audio]"));
}
#[test]
fn legacy_assistant_refusal_field_renders_refusal_text() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":null,",
"\"refusal\":\"I can't help with that request\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [refusal] I can't help with that request"
);
assert_eq!(chunks[0].role.as_deref(), Some("assistant"));
assert_eq!(chunks[0].tool_call_id.as_deref(), None);
}
#[test]
fn legacy_assistant_refusal_field_blank_drops_line() {
let jsonl = "{\"role\":\"assistant\",\"content\":null,\"refusal\":\" \"}\n";
let chunks = extract_jsonl(jsonl);
assert!(chunks.is_empty());
}
#[test]
fn legacy_assistant_refusal_field_missing_drops_line() {
let jsonl = "{\"role\":\"assistant\",\"content\":null}\n";
let chunks = extract_jsonl(jsonl);
assert!(chunks.is_empty());
}
#[test]
fn legacy_assistant_refusal_field_non_string_drops_line() {
let jsonl = "{\"role\":\"assistant\",\"content\":null,\"refusal\":{\"nested\":\"oops\"}}\n";
let chunks = extract_jsonl(jsonl);
assert!(chunks.is_empty());
}
#[test]
fn content_wins_over_legacy_assistant_refusal_field() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":\"here's an answer\",",
"\"refusal\":\"shouldn't surface\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] here's an answer");
assert!(!chunks[0].text.contains("[refusal]"));
}
#[test]
fn legacy_assistant_refusal_field_in_message_envelope_is_extracted() {
let jsonl = concat!(
"{\"type\":\"assistant\",\"sessionId\":\"sess-refusal\",",
"\"message\":{\"role\":\"assistant\",\"content\":null,",
"\"refusal\":\"nested refusal text\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert!(chunks[0].text.contains("[refusal] nested refusal text"));
assert_eq!(chunks[0].session_id.as_deref(), Some("sess-refusal"));
}
#[test]
fn legacy_assistant_refusal_field_shares_prefix_with_content_block_refusal() {
let flat = "{\"role\":\"assistant\",\"content\":null,\"refusal\":\"flat decline\"}\n";
let block = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"refusal\",\"refusal\":\"block decline\"}",
"]}\n"
);
let flat_chunks = extract_jsonl(flat);
let block_chunks = extract_jsonl(block);
assert_eq!(flat_chunks.len(), 1);
assert_eq!(block_chunks.len(), 1);
assert!(flat_chunks[0].text.contains("[refusal] flat decline"));
assert!(block_chunks[0].text.contains("[refusal] block decline"));
}
#[test]
fn legacy_assistant_reasoning_content_field_renders_thinking_prefix() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":null,",
"\"reasoning_content\":\"first, list the constraints...\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] [thinking] first, list the constraints..."
);
assert_eq!(chunks[0].role.as_deref(), Some("assistant"));
assert_eq!(chunks[0].tool_call_id.as_deref(), None);
}
#[test]
fn legacy_assistant_reasoning_content_camelcase_alias_extracts() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":null,",
"\"reasoningContent\":\"step 1: re-read the spec\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert!(
chunks[0]
.text
.contains("[thinking] step 1: re-read the spec")
);
}
#[test]
fn legacy_assistant_reasoning_content_snake_case_wins_over_camelcase() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":null,",
"\"reasoning_content\":\"snake wins\",",
"\"reasoningContent\":\"camel loses\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert!(chunks[0].text.contains("[thinking] snake wins"));
assert!(!chunks[0].text.contains("camel loses"));
}
#[test]
fn legacy_assistant_reasoning_content_blank_drops_line() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":null,",
"\"reasoning_content\":\" \"}\n"
);
let chunks = extract_jsonl(jsonl);
assert!(chunks.is_empty());
}
#[test]
fn legacy_assistant_reasoning_content_missing_drops_line() {
let jsonl = "{\"role\":\"assistant\",\"content\":null}\n";
let chunks = extract_jsonl(jsonl);
assert!(chunks.is_empty());
}
#[test]
fn legacy_assistant_reasoning_content_non_string_drops_line() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":null,",
"\"reasoning_content\":{\"nested\":\"oops\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert!(chunks.is_empty());
}
#[test]
fn content_wins_over_legacy_assistant_reasoning_content_field() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":\"the final answer\",",
"\"reasoning_content\":\"shouldn't surface here\"}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] the final answer");
assert!(!chunks[0].text.contains("[thinking]"));
assert!(!chunks[0].text.contains("shouldn't surface here"));
}
#[test]
fn legacy_assistant_reasoning_content_in_message_envelope_is_extracted() {
let jsonl = concat!(
"{\"type\":\"assistant\",\"sessionId\":\"sess-reasoning\",",
"\"message\":{\"role\":\"assistant\",\"content\":null,",
"\"reasoning_content\":\"nested reasoning trace\"}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert!(chunks[0].text.contains("[thinking] nested reasoning trace"));
assert_eq!(chunks[0].session_id.as_deref(), Some("sess-reasoning"));
}
#[test]
fn legacy_assistant_reasoning_content_shares_prefix_with_content_block_thinking() {
let flat = concat!(
"{\"role\":\"assistant\",\"content\":null,",
"\"reasoning_content\":\"flat reasoning\"}\n"
);
let anthropic_block = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"thinking\",\"thinking\":\"block reasoning\"}",
"]}\n"
);
let responses_block = concat!(
"{\"role\":\"assistant\",\"content\":[",
"{\"type\":\"reasoning_text\",\"text\":\"responses reasoning\"}",
"]}\n"
);
let flat_chunks = extract_jsonl(flat);
let anthropic_chunks = extract_jsonl(anthropic_block);
let responses_chunks = extract_jsonl(responses_block);
assert_eq!(flat_chunks.len(), 1);
assert_eq!(anthropic_chunks.len(), 1);
assert_eq!(responses_chunks.len(), 1);
assert!(flat_chunks[0].text.contains("[thinking] flat reasoning"));
assert!(
anthropic_chunks[0]
.text
.contains("[thinking] block reasoning")
);
assert!(
responses_chunks[0]
.text
.contains("[thinking] responses reasoning")
);
}
#[test]
fn chat_completions_message_url_citation_appends_after_content() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":\"The capital of France is Paris.\",",
"\"annotations\":[",
"{\"type\":\"url_citation\",\"url_citation\":{",
"\"url\":\"https://en.wikipedia.org/wiki/Paris\",",
"\"title\":\"Paris - Wikipedia\",",
"\"start_index\":0,\"end_index\":30}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] The capital of France is Paris.\n[url_citation] https://en.wikipedia.org/wiki/Paris Paris - Wikipedia"
);
}
#[test]
fn chat_completions_message_url_citation_without_title_drops_title_segment() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":\"see source\",",
"\"annotations\":[",
"{\"type\":\"url_citation\",\"url_citation\":{\"url\":\"https://example.com/a\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] see source\n[url_citation] https://example.com/a"
);
}
#[test]
fn chat_completions_message_multiple_url_citations_join_in_array_order() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":\"compare sources\",",
"\"annotations\":[",
"{\"type\":\"url_citation\",\"url_citation\":{\"url\":\"https://a.example/\",\"title\":\"Alpha\"}},",
"{\"type\":\"url_citation\",\"url_citation\":{\"url\":\"https://b.example/\",\"title\":\"Beta\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] compare sources\n[url_citation] https://a.example/ Alpha\n[url_citation] https://b.example/ Beta"
);
}
#[test]
fn chat_completions_message_without_annotations_renders_plain_content() {
let jsonl = "{\"role\":\"assistant\",\"content\":\"plain body\"}\n";
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] plain body");
}
#[test]
fn chat_completions_message_with_empty_annotations_array_renders_plain_content() {
let jsonl = "{\"role\":\"assistant\",\"content\":\"plain body\",\"annotations\":[]}\n";
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] plain body");
}
#[test]
fn chat_completions_message_with_only_unknown_annotation_types_renders_plain_content() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":\"plain body\",",
"\"annotations\":[",
"{\"type\":\"future_citation\",\"foo\":\"bar\"},",
"{\"no_type\":true}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] plain body");
}
#[test]
fn chat_completions_message_url_citation_missing_inner_object_is_skipped() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":\"plain body\",",
"\"annotations\":[",
"{\"type\":\"url_citation\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] plain body");
}
#[test]
fn chat_completions_message_url_citation_missing_url_is_skipped() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":\"plain body\",",
"\"annotations\":[",
"{\"type\":\"url_citation\",\"url_citation\":{\"title\":\"only title\"}}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] plain body");
}
#[test]
fn chat_completions_message_flat_responses_shape_is_skipped() {
let jsonl = concat!(
"{\"role\":\"assistant\",\"content\":\"plain body\",",
"\"annotations\":[",
"{\"type\":\"url_citation\",\"url\":\"https://example.com/\",",
"\"title\":\"Example\"}",
"]}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(chunks[0].text, "[assistant] plain body");
}
#[test]
fn chat_completions_message_annotations_pick_up_from_inner_message_envelope() {
let jsonl = concat!(
"{\"type\":\"assistant\",\"sessionId\":\"s1\",",
"\"message\":{\"role\":\"assistant\",\"content\":\"see docs\",",
"\"annotations\":[",
"{\"type\":\"url_citation\",\"url_citation\":{\"url\":\"https://inner.example/\"}}",
"]}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] see docs\n[url_citation] https://inner.example/"
);
assert_eq!(chunks[0].session_id.as_deref(), Some("s1"));
}
#[test]
fn chat_completions_message_annotations_when_outer_content_wins_use_outer_scope() {
let jsonl = concat!(
"{\"type\":\"assistant\",\"role\":\"assistant\",",
"\"content\":\"outer body\",",
"\"annotations\":[",
"{\"type\":\"url_citation\",\"url_citation\":{\"url\":\"https://outer.example/\"}}",
"],",
"\"message\":{\"content\":\"inner body\",",
"\"annotations\":[",
"{\"type\":\"url_citation\",\"url_citation\":{\"url\":\"https://inner.example/\"}}",
"]}}\n"
);
let chunks = extract_jsonl(jsonl);
assert_eq!(chunks.len(), 1);
assert_eq!(
chunks[0].text,
"[assistant] outer body\n[url_citation] https://outer.example/"
);
}
}