use super::*;
use serde_json::Value;
pub(super) fn append_blocks(
blocks: &mut Vec<ToolBlock>,
input: &ToolCardInput<'_>,
role: ToolCardRole,
outcome: Option<ToolOutcome>,
) {
if role == ToolCardRole::SubagentBatch {
let report = input.detail.and_then(|detail| {
TaskBatchTelemetry::parse_for_tasks(
&detail.metadata["subagent_telemetry"],
&detail.params,
)
});
let total = report.as_ref().map(|report| report.tasks.len() as u64);
let block = report.map_or_else(
|| ToolBlock::Results {
rows: [
"Tasks total",
"Tasks done",
"Tasks failed",
"Tasks running",
"Tasks unknown",
"Tasks cancelled",
]
.into_iter()
.map(|label| ResultRow {
label: label.into(),
value: None,
outcome: ResultOutcome::Unknown,
})
.collect(),
},
|report| report.block(),
);
let mut block = block;
if let ToolBlock::Results { rows } = &mut block {
append_child_facts(rows, total, input.children.len());
}
blocks.insert(0, block);
return;
}
if role != ToolCardRole::CodeMode {
return;
}
let empty = Value::Null;
let detail = input.detail;
let execution = detail.map_or(&empty, |detail| &detail.metadata["code_mode_execution"]);
let number = |key: &str| execution[key].as_u64().map(|value| value.to_string());
let mut rows = Vec::new();
let mut fact = |label: &str, value: Option<String>| {
rows.push(ResultRow {
label: label.into(),
value,
outcome: ResultOutcome::Unknown,
})
};
fact(
"Script outcome",
Some(
match outcome {
Some(ToolOutcome::Success) => "success",
Some(ToolOutcome::Failure) => "failure",
Some(ToolOutcome::Cancelled) => "cancelled",
Some(ToolOutcome::Interrupted) => "interrupted",
Some(ToolOutcome::Unknown) => "unknown",
None => "running",
}
.into(),
),
);
fact(
"Code Mode intent",
detail
.and_then(|detail| detail.params["intent"].as_str())
.map(sanitized_single_line),
);
for (label, key) in [
("Total calls", "inner_calls"),
("Successful calls", "successful"),
("Failed calls", "recoverable_failures"),
("Unknown calls", "unknown_outcomes"),
("Running calls", "running_calls"),
("Elapsed milliseconds", "elapsed_ms"),
("Recoverable failures", "recoverable_failures"),
("Warnings", "warning_count"),
("Changed paths", "changed_path_count"),
] {
fact(label, number(key));
}
fact(
"Response token estimate",
detail
.and_then(|detail| detail.metadata["code_mode_response_token_estimate"].as_u64())
.map(|value| value.to_string()),
);
fact(
"Change count qualifier",
execution["changed_paths_incomplete"]
.as_bool()
.map(|incomplete| if incomplete { "at_least" } else { "exact" }.into()),
);
fact("Completed actions remain applied", Some("true".into()));
fact("Rollback", Some("false".into()));
fact("External effects may be untracked", Some("true".into()));
fact(
"Execution persistence",
detail
.and_then(|detail| detail.metadata["telemetry_persistence"].as_str())
.filter(|value| matches!(*value, "recorded" | "unavailable"))
.map(str::to_owned),
);
let warnings = ["recoverable_failures", "unknown_outcomes", "warning_count"]
.map(|key| execution[key].as_u64());
fact(
"Completed with warnings",
if outcome != Some(ToolOutcome::Success) {
None
} else if warnings
.iter()
.any(|value| value.is_some_and(|value| value > 0))
{
Some("true".into())
} else if warnings.iter().all(Option::is_some) {
Some("false".into())
} else {
None
},
);
let warnings = execution["warnings"].as_array();
let paths = execution["changed_paths"].as_array();
let shown_warnings = warnings.map_or(0, |values| values.len().min(2));
let shown_paths = paths.map_or(0, |values| values.len().min(3));
fact(
"Warnings omitted",
execution["warning_count"]
.as_u64()
.and_then(|count| count.checked_sub(shown_warnings as u64))
.map(|value| value.to_string()),
);
fact(
"Changed paths omitted",
execution["changed_path_count"]
.as_u64()
.and_then(|count| count.checked_sub(shown_paths as u64))
.map(|value| value.to_string()),
);
append_child_facts(
&mut rows,
execution["inner_calls"].as_u64(),
input.children.len(),
);
blocks.insert(0, ToolBlock::Results { rows });
let mut previews = Vec::new();
for (label, values, limit) in [("Warning", warnings, 2), ("Changed path", paths, 3)] {
for value in values
.into_iter()
.flatten()
.take(limit)
.filter_map(Value::as_str)
{
previews.push(ResultRow {
label: label.into(),
value: Some(sanitized_single_line(value)),
outcome: ResultOutcome::Unknown,
});
}
}
if !previews.is_empty() {
blocks.push(ToolBlock::Results { rows: previews });
}
}
fn append_child_facts(rows: &mut Vec<ResultRow>, total: Option<u64>, shown: usize) {
let omitted = total.and_then(|total| total.checked_sub(shown as u64));
for (label, value) in [
(
"Child references complete",
omitted.map(|count| (count == 0).to_string()),
),
(
"Child references omitted",
omitted.map(|count| count.to_string()),
),
] {
rows.push(ResultRow {
label: label.into(),
value,
outcome: ResultOutcome::Unknown,
});
}
}
pub(crate) fn core_label(label: &str) -> bool {
matches!(
label,
"Script outcome"
| "Total calls"
| "Completed with warnings"
| "Failed calls"
| "Unknown calls"
| "Running calls"
| "Warnings"
| "Changed paths"
| "Warnings omitted"
| "Changed paths omitted"
| "Child references complete"
| "Child references omitted"
| "Change count qualifier"
| "Completed actions remain applied"
| "Rollback"
| "External effects may be untracked"
| "Tasks total"
| "Tasks done"
| "Tasks cancelled"
| "Tasks failed"
| "Tasks unknown"
| "Tasks running"
| "Task outcome"
| "Task changed paths"
| "Task failed calls"
| "Task unknown calls"
| "Task calls with effects"
| "Task activity count"
| "Task activity omitted"
| "Task facts limited"
)
}