build: a bare {chain} in a mail body goes, on its own line or inline
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
88e54ed17f
commit
0a02b4db1a
+17
-7
@@ -1045,14 +1045,23 @@ fn keep_links(fallback: &Value, merged: &mut Value) {
|
||||
for (bucket, stages) in fb {
|
||||
let Some(ms) = mb.get_mut(bucket).and_then(Value::as_object_mut) else { continue };
|
||||
for (stage, spec) in stages.as_object().into_iter().flatten() {
|
||||
let Some(link) = spec["body"].as_str().and_then(|b| b.lines().find(|l| l.contains("{site}/decide/"))) else { continue };
|
||||
let link = spec["body"].as_str().and_then(|b| b.lines().find(|l| l.contains("{site}/decide/")));
|
||||
let Some(body) = ms.get_mut(stage).and_then(|m| m.get_mut("body")) else { continue };
|
||||
let Some(text) = body.as_str() else { continue };
|
||||
if text.contains("/decide/") {
|
||||
continue;
|
||||
// A bare `{chain}` outside a link is the record id pasted
|
||||
// into prose, which a model does when told to keep
|
||||
// placeholders; it goes, on its own line or inline.
|
||||
let cleaned: Vec<String> = text
|
||||
.lines()
|
||||
.map(|l| if l.contains("/decide/") { l.to_string() } else { l.replace("{chain}", "").split_whitespace().collect::<Vec<_>>().join(" ") })
|
||||
.collect();
|
||||
let mut cleaned = cleaned.join("\n").trim_end().to_string();
|
||||
if let Some(link) = link {
|
||||
if !cleaned.contains("/decide/") {
|
||||
cleaned = format!("{cleaned}\n\n{link}");
|
||||
}
|
||||
}
|
||||
let kept: Vec<&str> = text.lines().filter(|l| l.trim() != "{chain}").collect();
|
||||
*body = Value::String(format!("{}\n\n{link}", kept.join("\n").trim_end()));
|
||||
*body = Value::String(cleaned);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1723,11 +1732,12 @@ mod tests {
|
||||
#[test]
|
||||
fn a_models_mail_keeps_the_submitters_link() {
|
||||
let fallback = json!({ "leaks": { "open": { "subject": "s", "body": "Hello,\n\nGot it.\n\nWhat you can do next: {site}/decide/leak?chain={chain}&email={email}\n\nI at i@b.example" } } });
|
||||
let mut merged = json!({ "leaks": { "open": { "subject": "Got it", "body": "Hi,\n\nWe have it.\n\n{chain}" } } });
|
||||
let mut merged = json!({ "leaks": { "open": { "subject": "Got it", "body": "Hi,\n\nWe have it. {chain}\n\n{chain}" } } });
|
||||
keep_links(&fallback, &mut merged);
|
||||
let body = merged["leaks"]["open"]["body"].as_str().unwrap();
|
||||
assert!(body.ends_with("What you can do next: {site}/decide/leak?chain={chain}&email={email}"));
|
||||
assert!(!body.contains("\n{chain}"));
|
||||
assert!(!body.contains("it. {chain}") && !body.contains("\n{chain}"));
|
||||
assert!(body.starts_with("Hi,\n\nWe have it."));
|
||||
// A body that kept its link is left alone.
|
||||
let mut fine = json!({ "leaks": { "open": { "subject": "s", "body": "Withdraw here: {site}/decide/leak?chain={chain}&email={email}" } } });
|
||||
keep_links(&fallback, &mut fine);
|
||||
|
||||
Reference in New Issue
Block a user