use super::*;
pub(super) fn web_card(
state: &MissionControlState,
id: TranscriptCardId,
link: Option<TranscriptActivityLink>,
) -> TranscriptCard {
let node = link
.as_ref()
.and_then(|link| state.nodes.get(&link.activity_id));
let detail = node.and_then(|node| node.tool_detail.as_ref());
let status = node
.map(|node| transcript_status_from_activity(node.status))
.unwrap_or_else(|| transcript_tool_status(state, id.entry_index));
let operation = detail
.and_then(|detail| detail.params.get("operation"))
.and_then(serde_json::Value::as_str)
.unwrap_or("web");
let target = detail.and_then(|detail| {
["query", "url", "reference"]
.iter()
.find_map(|key| detail.params.get(key).and_then(serde_json::Value::as_str))
});
let mut metadata = Vec::new();
if let Some(results) = detail
.and_then(|detail| detail.metadata.get("results"))
.and_then(serde_json::Value::as_u64)
{
metadata.push(format!("{results} results"));
}
if detail
.and_then(|detail| detail.metadata.get("truncated"))
.and_then(serde_json::Value::as_bool)
== Some(true)
{
metadata.push("output truncated".to_string());
}
let mut lines = target
.map(sanitized_single_line)
.into_iter()
.collect::<Vec<_>>();
match status {
TranscriptCardStatus::Success => {
if let Some(detail) = detail {
let preview = bounded_preview_lines(detail.output.as_ref());
if !preview.is_empty() {
lines.push(preview);
}
}
}
TranscriptCardStatus::Failed => lines.push(bounded_error_line(
detail
.map(|detail| detail.output.as_ref())
.unwrap_or("web request failed"),
)),
TranscriptCardStatus::Canceled => lines.push("canceled".to_string()),
TranscriptCardStatus::Running | TranscriptCardStatus::None => {}
}
TranscriptCard {
id,
role: TranscriptCardRole::Web,
status,
title: match operation {
"search" => "Web Search",
"open" => "Web Open",
_ => "Web",
}
.to_string(),
metadata,
body: lines.join("\n"),
body_lines: Vec::new(),
children: Vec::new(),
activity_rows: Vec::new(),
subagent_card: None,
}
}