Build the prompt with an explicitly specified style.
(&self, style: AgentStyle)
| 470 | |
| 471 | /// Build the prompt with an explicitly specified style. |
| 472 | fn build_with_style(&self, style: AgentStyle) -> String { |
| 473 | let mut parts: Vec<String> = Vec::new(); |
| 474 | |
| 475 | // Normalize line endings: strip \r so string matching works on Windows |
| 476 | // where include_str! may produce \r\n if the file has CRLF endings. |
| 477 | let base_prompt = style.base_prompt().replace('\r', ""); |
| 478 | let default_role_line = DEFAULT_ROLE_LINE.replace('\r', ""); |
| 479 | let default_response_format = DEFAULT_RESPONSE_FORMAT.replace('\r', ""); |
| 480 | |
| 481 | // 1. Role: for GeneralPurpose, replace the default role line. |
| 482 | // For other styles (Plan, Explore, Verification), prepend custom role since |
| 483 | // those prompts have their own identity embedded. |
| 484 | let core = if let Some(ref role) = self.role { |
| 485 | if style == AgentStyle::GeneralPurpose { |
| 486 | let custom_role = format!( |
| 487 | "{}. You operate in an agentic loop: inspect, act with tools, observe results, and continue until the user's request is genuinely complete.", |
| 488 | role.trim_end_matches('.') |
| 489 | ); |
| 490 | base_prompt.replace(&default_role_line, &custom_role) |
| 491 | } else { |
| 492 | // Prepend custom role for other styles |
| 493 | format!("{}\n\n{}", role, base_prompt) |
| 494 | } |
| 495 | } else { |
| 496 | base_prompt |
| 497 | }; |
| 498 | |
| 499 | // 2. Core: strip the default response format section if custom one is provided |
| 500 | let core = if self.response_style.is_some() { |
| 501 | core.replace(&default_response_format, "") |
| 502 | .trim_end() |
| 503 | .to_string() |
| 504 | } else { |
| 505 | core.trim_end().to_string() |
| 506 | }; |
| 507 | |
| 508 | parts.push(core); |
| 509 | |
| 510 | // 2b. Safety boundaries — single source of truth, appended uniformly so |
| 511 | // every style and delegated subagent (which build through this path) |
| 512 | // carries injection-hygiene, secret-handling, and malware-refusal rules. |
| 513 | parts.push(BOUNDARIES.replace('\r', "").trim_end().to_string()); |
| 514 | |
| 515 | // 3. Custom response style (replaces default Response Format) |
| 516 | if let Some(ref style) = self.response_style { |
| 517 | parts.push(format!("## Response Format\n\n{}", style)); |
| 518 | } |
| 519 | |
| 520 | // 4. Guidelines: style-specific + custom |
| 521 | let style_guidelines = style.guidelines(); |
| 522 | if style_guidelines.is_some() || self.guidelines.is_some() { |
| 523 | let mut guidelines_parts = Vec::new(); |
| 524 | if let Some(sg) = style_guidelines { |
| 525 | guidelines_parts.push(sg.to_string()); |
| 526 | } |
| 527 | if let Some(ref g) = self.guidelines { |
| 528 | guidelines_parts.push(g.clone()); |
| 529 | } |
no test coverage detected