agent: Fix Gemini refusing all requests with file-based tool calls (#38705)

Ben Brandt created

Solves an issue where Google APIs refuse all requests with file-based
tool calls attached.
This seems to get triggered in the case where:

- copy_path + another file-based tool call is enabled
- default terminal is `/bin/bash` or something similar

It is unclear why this is happening, but removing the terminal commands
in those tool calls seems to have solved the issue.

Closes #37180 and #37414

Release Notes:

- agent: Fix Gemini refusing requests with certain profiles/systems.

Change summary

crates/agent2/src/templates/system_prompt.hbs    | 18 +++++++++++-------
crates/agent2/src/tools/copy_path_tool.rs        |  4 ++--
crates/agent2/src/tools/create_directory_tool.rs |  2 +-
3 files changed, 14 insertions(+), 10 deletions(-)

Detailed changes

crates/agent2/src/templates/system_prompt.hbs 🔗

@@ -48,16 +48,15 @@ The one exception to this is if the user references something you don't know abo
 ## Code Block Formatting
 
 Whenever you mention a code block, you MUST use ONLY use the following format:
+
 ```path/to/Something.blah#L123-456
 (code goes here)
 ```
-The `#L123-456` means the line number range 123 through 456, and the path/to/Something.blah
-is a path in the project. (If there is no valid path in the project, then you can use
-/dev/null/path.extension for its path.) This is the ONLY valid way to format code blocks, because the Markdown parser
-does not understand the more common ```language syntax, or bare ``` blocks. It only
-understands this path-based syntax, and if the path is missing, then it will error and you will have to do it over again.
+
+The `#L123-456` means the line number range 123 through 456, and the path/to/Something.blah is a path in the project. (If there is no valid path in the project, then you can use /dev/null/path.extension for its path.) This is the ONLY valid way to format code blocks, because the Markdown parser does not understand the more common ```language syntax, or bare ``` blocks. It only understands this path-based syntax, and if the path is missing, then it will error and you will have to do it over again.
 Just to be really clear about this, if you ever find yourself writing three backticks followed by a language name, STOP!
 You have made a mistake. You can only ever put paths after triple backticks!
+
 <example>
 Based on all the information I've gathered, here's a summary of how this system works:
 1. The README file is loaded into the system.
@@ -74,6 +73,7 @@ This is the last header in the README.
 ```
 4. Finally, it passes this information on to the next process.
 </example>
+
 <example>
 In Markdown, hash marks signify headings. For example:
 ```/dev/null/example.md#L1-3
@@ -82,6 +82,7 @@ In Markdown, hash marks signify headings. For example:
 ### Level 3 heading
 ```
 </example>
+
 Here are examples of ways you must never render code blocks:
 <bad_example_do_not_do_this>
 In Markdown, hash marks signify headings. For example:
@@ -91,7 +92,9 @@ In Markdown, hash marks signify headings. For example:
 ### Level 3 heading
 ```
 </bad_example_do_not_do_this>
+
 This example is unacceptable because it does not include the path.
+
 <bad_example_do_not_do_this>
 In Markdown, hash marks signify headings. For example:
 ```markdown
@@ -101,14 +104,15 @@ In Markdown, hash marks signify headings. For example:
 ```
 </bad_example_do_not_do_this>
 This example is unacceptable because it has the language instead of the path.
+
 <bad_example_do_not_do_this>
 In Markdown, hash marks signify headings. For example:
     # Level 1 heading
     ## Level 2 heading
     ### Level 3 heading
 </bad_example_do_not_do_this>
-This example is unacceptable because it uses indentation to mark the code block
-instead of backticks with a path.
+This example is unacceptable because it uses indentation to mark the code block instead of backticks with a path.
+
 <bad_example_do_not_do_this>
 In Markdown, hash marks signify headings. For example:
 ```markdown

crates/agent2/src/tools/copy_path_tool.rs 🔗

@@ -9,14 +9,14 @@ use std::sync::Arc;
 use util::markdown::MarkdownInlineCode;
 
 /// Copies a file or directory in the project, and returns confirmation that the copy succeeded.
-/// Directory contents will be copied recursively (like `cp -r`).
+/// Directory contents will be copied recursively.
 ///
 /// This tool should be used when it's desirable to create a copy of a file or directory without modifying the original.
 /// It's much more efficient than doing this by separately reading and then writing the file or directory's contents, so this tool should be preferred over that approach whenever copying is the goal.
 #[derive(Debug, Serialize, Deserialize, JsonSchema)]
 pub struct CopyPathToolInput {
     /// The source path of the file or directory to copy.
-    /// If a directory is specified, its contents will be copied recursively (like `cp -r`).
+    /// If a directory is specified, its contents will be copied recursively.
     ///
     /// <example>
     /// If the project has the following files:

crates/agent2/src/tools/create_directory_tool.rs 🔗

@@ -11,7 +11,7 @@ use crate::{AgentTool, ToolCallEventStream};
 
 /// Creates a new directory at the specified path within the project. Returns confirmation that the directory was created.
 ///
-/// This tool creates a directory and all necessary parent directories (similar to `mkdir -p`). It should be used whenever you need to create new directories within the project.
+/// This tool creates a directory and all necessary parent directories. It should be used whenever you need to create new directories within the project.
 #[derive(Debug, Serialize, Deserialize, JsonSchema)]
 pub struct CreateDirectoryToolInput {
     /// The path of the new directory.