a3s_code_core/
transcript.rs1pub fn product_user_text(text: &str) -> String {
12 let normalized = text.replace("\r\n", "\n").replace('\r', "\n");
13 let mut working = normalized.as_str();
14
15 working = strip_prefix_fence(working, "```open-reply-review-findings");
16
17 let planner_markers = [
18 "\nPlanner-optimized request:",
19 "\n规划优化请求:",
20 "\n规划优化请求:",
21 "\n优化后的请求:",
22 "\n优化后的请求:",
23 "\nHook-modified planning task:",
26 "\nPlanning hook guidance:",
27 ];
28 for marker in planner_markers {
29 if let Some((before, _)) = working.split_once(marker) {
30 working = before;
31 }
32 }
33
34 if let Some((before, _)) = working.split_once("\n\nAutomatic subagent context:\n") {
35 working = before;
36 }
37
38 working = strip_user_prompt_hook_context(working);
41
42 let user_markers = [
45 "\nLatest user message:\n",
46 "\nLatest user message:",
47 "\n最新用户消息:",
48 "\n最新用户消息:",
49 "\nUser task:\n",
50 "\nUser task:",
51 "\n用户任务:",
52 "\n用户任务:",
53 ];
54 let mut task = working;
55 for marker in user_markers {
56 if let Some((_, after)) = working.rsplit_once(marker) {
57 task = after;
58 break;
59 }
60 }
61 if std::ptr::eq(task, working) {
62 let leading_markers = [
63 "Latest user message:\n",
64 "Latest user message:",
65 "最新用户消息:",
66 "最新用户消息:",
67 "User task:\n",
68 "User task:",
69 "用户任务:",
70 "用户任务:",
71 ];
72 for marker in leading_markers {
73 if let Some(after) = working.strip_prefix(marker) {
74 task = after;
75 break;
76 }
77 }
78 }
79
80 let trimmed = task
81 .trim()
82 .trim_start_matches("Original user request:")
83 .trim_start_matches("Original user request:")
84 .trim();
85
86 if is_pure_runtime_steering(trimmed) || trimmed.is_empty() {
87 String::new()
88 } else {
89 trimmed.to_string()
90 }
91}
92
93pub fn is_wire_only_user_text(text: &str) -> bool {
95 product_user_text(text).is_empty() && !text.trim().is_empty()
96}
97
98fn strip_prefix_fence<'a>(text: &'a str, fence: &str) -> &'a str {
99 let trimmed = text.trim_start();
100 if !trimmed.starts_with(fence) {
101 return text;
102 }
103 let after_open = &trimmed[fence.len()..];
104 let after_open = after_open.strip_prefix('\n').unwrap_or(after_open);
105 if let Some((_, rest)) = after_open.split_once("\n```") {
106 let rest = rest.trim_start_matches('\n');
107 if rest.is_empty() {
108 text
109 } else {
110 rest
111 }
112 } else {
113 text
114 }
115}
116
117fn strip_user_prompt_hook_context(text: &str) -> &str {
118 const OPEN: &str = "\n\n<user-prompt-hook-context>\n";
119 if let Some(start) = text.find(OPEN) {
120 return text[..start].trim_end();
123 }
124 if let Some(start) = text.find("<user-prompt-hook-context>") {
125 return text[..start].trim_end();
126 }
127 text
128}
129
130fn is_pure_runtime_steering(text: &str) -> bool {
131 let text = text.trim_start();
132 if text.is_empty() {
133 return false;
134 }
135 (text.starts_with("Delegated plan step '") && text.contains(" failed:\n"))
136 || (text.starts_with("Tool '")
137 && (text.contains(" execution was REJECTED")
138 || text.contains(" confirmation failed:")
139 || text.contains(" cancelled by caller")))
140 || text.starts_with("Delegated parallel plan wave completed with failures:")
141 || (text.starts_with("Goal:") && text.contains("Execute the following plan step by step:"))
142 || text.starts_with("Execute step ")
143 || text.starts_with("Execute the following plan step by step:")
144 || text.starts_with("[Context Summary:")
145 || text.starts_with("Tool-use budget reached.")
146 || text.starts_with('{') && text.contains("\"type\":\"parallel_results\"")
147 || text.starts_with("Address each open review finding")
148}
149
150#[cfg(test)]
151mod tests {
152 use super::{is_wire_only_user_text, product_user_text};
153
154 #[test]
155 fn unwraps_desktop_user_task() {
156 let text = "A3S Desktop workbench context:\n- Active workbench: Office.\n\nUser task:\n规划如何开发一个游戏引擎?";
157 assert_eq!(product_user_text(text), "规划如何开发一个游戏引擎?");
158 assert!(!is_wire_only_user_text(text));
159 }
160
161 #[test]
162 fn unwraps_desktop_latest_user_message() {
163 let text = "A3S Desktop workbench context:\n- Active workbench: Office.\n\nLatest user message:\n再试试";
164 assert_eq!(product_user_text(text), "再试试");
165 }
166
167 #[test]
168 fn unwraps_planner_wrapper_with_latest_user_message() {
169 let text = "Original user request:\nA3S Desktop workbench context:\nLatest user message:\n再试试\n\nPlanner-optimized request:\n再试试\n当前请求仅表示“再试试”,需先澄清。";
170 assert_eq!(product_user_text(text), "再试试");
171 }
172
173 #[test]
174 fn strips_pre_prompt_hook_context_appendix() {
175 let text = "Ship the release\n\n<user-prompt-hook-context>\npolicy note\n</user-prompt-hook-context>";
176 assert_eq!(product_user_text(text), "Ship the release");
177 }
178
179 #[test]
180 fn strips_pre_planning_hook_appendix() {
181 let text = [
182 "Original user request:",
183 "A3S Desktop workbench context:",
184 "User task:",
185 "Ship the release",
186 "",
187 "Hook-modified planning task:",
188 "Rewrite the release checklist first",
189 "",
190 "Planning hook guidance:",
191 "Selected strategy: careful",
192 ]
193 .join("\n");
194 assert_eq!(product_user_text(&text), "Ship the release");
195 }
196
197 #[test]
198 fn keeps_human_skill_slash_spelling_from_desktop_compose() {
199 let text = "A3S Desktop workbench context:\n- Active workbench: Office.\n\nUser task:\n/a3s-box run nginx";
200 assert_eq!(product_user_text(text), "/a3s-box run nginx");
201 }
202
203 #[test]
204 fn unwraps_planner_optimized_wrapper() {
205 let text = "Original user request:\nA3S Desktop workbench context:\nUser task: 工作区有哪些文件?\nPlanner-optimized request:\nlist files";
206 assert_eq!(product_user_text(text), "工作区有哪些文件?");
207 }
208
209 #[test]
210 fn strips_auto_delegation_appendix() {
211 let text = "Ship the release\n\nAutomatic subagent context:\n{\"tasks\":[]}\n\nUse the subagent findings as evidence, but make the final decision yourself.";
212 assert_eq!(product_user_text(text), "Ship the release");
213 }
214
215 #[test]
216 fn blanks_plan_execute_goal_chrome() {
217 let text = "Goal: ship it\n\nExecute the following plan step by step:\n1. Draft\n2. Review";
218 assert_eq!(product_user_text(text), "");
219 assert!(is_wire_only_user_text(text));
220 }
221
222 #[test]
223 fn blanks_plan_execute_step_chrome() {
224 let text = "Execute step 2: Draft the architecture";
225 assert_eq!(product_user_text(text), "");
226 assert!(is_wire_only_user_text(text));
227 }
228
229 #[test]
230 fn blanks_compaction_summary_chrome() {
231 let text = "[Context Summary: prior turns compressed]\nKeep working.";
232 assert_eq!(product_user_text(text), "");
233 assert!(is_wire_only_user_text(text));
234 }
235
236 #[test]
237 fn unwraps_open_reply_review_findings_fence() {
238 let text =
239 "```open-reply-review-findings\nDATA\n```\nUser task:\nFix the failing assertion";
240 assert_eq!(product_user_text(text), "Fix the failing assertion");
241 }
242
243 #[test]
244 fn message_constructors_segregate_wire_and_transcript() {
245 use crate::llm::Message;
246
247 let product = Message::user("hello");
248 assert!(product.is_product_transcript());
249 assert_eq!(product.transcript_display_text(), "hello");
250
251 let wire = Message::user_wire("Execute step 1: Survey");
252 assert!(!wire.is_product_transcript());
253 assert_eq!(wire.text(), "Execute step 1: Survey");
254
255 let dual = Message::user_for_model_with_transcript(
256 "A3S Desktop workbench context:\n\nUser task:\n规划引擎",
257 "规划引擎",
258 );
259 assert!(dual.is_product_transcript());
260 assert_eq!(dual.transcript_display_text(), "规划引擎");
261 assert!(dual.text().contains("User task:"));
262
263 let address_reply = Message::assistant_wire("Finding f1: rebutted with tool exit 0");
264 assert!(!address_reply.is_product_transcript());
265 assert_eq!(
266 address_reply.text(),
267 "Finding f1: rebutted with tool exit 0"
268 );
269 }
270}