diff --git a/packages/core/src/core/__snapshots__/prompts.test.ts.snap b/packages/core/src/core/__snapshots__/prompts.test.ts.snap index 79278fbf..0887eebc 100644 --- a/packages/core/src/core/__snapshots__/prompts.test.ts.snap +++ b/packages/core/src/core/__snapshots__/prompts.test.ts.snap @@ -63,6 +63,7 @@ When requested to perform tasks like fixing bugs, adding features, refactoring, - **File Paths:** Always use absolute paths when referring to files with tools like 'read_file' or 'write_file'. Relative paths are not supported. You must provide an absolute path. - **Parallelism:** Execute multiple independent tool calls in parallel when feasible (i.e. searching the codebase). - **Command Execution:** Use the 'run_shell_command' tool for running shell commands, remembering the safety rule to explain modifying commands first. +- **Tool Calling (Critical):** Never emit pseudo tool-call markers (e.g. "tool_call: ...") in normal text. When you need to use a tool, call it using the tool-calling mechanism. - **Background Processes:** Use background processes (via \`&\`) for commands that are unlikely to stop on their own, e.g. \`node server.js &\`. If unsure, ask the user. - **Interactive Commands:** Try to avoid shell commands that are likely to require user interaction (e.g. \`git rebase -i\`). Use non-interactive versions of commands (e.g. \`npm init -y\` instead of \`npm init\`) when available, and otherwise remind the user that interactive shell commands are not supported and may cause hangs until canceled by the user. - **Remembering Facts:** Use the 'save_memory' tool to remember specific, *user-related* facts or preferences when the user explicitly asks, or when they state a clear, concise piece of information that would help personalize or streamline *your future interactions with them* (e.g., preferred coding style, common project paths they use, personal tool aliases). This tool is for user-specific information that should persist across sessions. Do *not* use it for general project context or information that belongs in project-specific \`GEMINI.md\` files. If unsure whether to save something, you can ask the user, "Should I remember that for you?" @@ -92,24 +93,24 @@ model: true user: list files here. -model: [tool_call: list_directory for path '.'] +model: I'll use the list_directory tool to list files in '.'. user: start the server implemented in server.js -model: [tool_call: run_shell_command for 'node server.js &' because it must run in the background] +model: I'll run \`node server.js &\` using the run_shell_command tool (it must run in the background). user: Refactor the auth logic in src/auth.py to use the requests library instead of urllib. model: Okay, I can refactor 'src/auth.py'. First, I'll analyze the code and check for a test safety net before planning any changes. -[tool_call: glob for path 'tests/test_auth.py'] -[tool_call: read_file for absolute_path '/path/to/tests/test_auth.py'] +(I'll search for tests: glob on 'tests/test_auth.py') +(I'll read the test file: read_file on '/path/to/tests/test_auth.py') (After analysis) Great, 'tests/test_auth.py' exists and covers the core authentication logic. With this safety net in place, I can safely plan the refactoring. I'll also confirm 'requests' is a dependency. -[tool_call: read_file for absolute_path '/path/to/requirements.txt'] +(I'll check dependencies: read_file on '/path/to/requirements.txt') (After analysis) Looks good, 'requests' is available. @@ -122,9 +123,9 @@ Here's the plan: Should I proceed? user: Yes model: -[tool_call: write_file or replace to apply the refactoring to 'src/auth.py'] +(I'll apply the refactor using write_file or replace on 'src/auth.py') Refactoring complete. Running verification... -[tool_call: run_shell_command for 'ruff check src/auth.py && pytest'] +(I'll run verification using run_shell_command: \`ruff check src/auth.py && pytest\`) (After verification passes) All checks passed. This is a stable checkpoint. @@ -139,23 +140,23 @@ model: I can run \`rm -rf ./temp\`. This will permanently delete the directory a user: Write tests for someFile.ts model: Okay, I can write those tests. First, I'll read \`someFile.ts\` to understand its functionality. -[tool_call: read_file for absolute_path '/path/to/someFile.ts' or use glob to find \`someFile.ts\` if its location is unknown] +(I'll read the file: read_file on '/path/to/someFile.ts', or use glob if its location is unknown) Now I'll look for existing or related test files to understand current testing conventions and dependencies. -[tool_call: read_many_files for paths ['**/*.test.ts', 'src/**/*.spec.ts'] assuming someFile.ts is in the src directory] +(I'll read related tests: read_many_files on ['**/*.test.ts', 'src/**/*.spec.ts']) (After reviewing existing tests and the file content) -[tool_call: write_file to create /path/to/someFile.test.ts with the test code] +(I'll write the new test file: write_file on '/path/to/someFile.test.ts') I've written the tests. Now I'll run the project's test command to verify them. -[tool_call: run_shell_command for 'npm run test'] +(I'll run tests using run_shell_command: \`npm run test\`) user: How do I update the user's profile information in this system? model: I'm not immediately sure how user profile information is updated. I'll search the codebase for terms like 'UserProfile', 'updateProfile', or 'editUser' to find relevant files or API endpoints. -[tool_call: search_file_content for pattern 'UserProfile|updateProfile|editUser'] +(I'll search the codebase: search_file_content on 'UserProfile|updateProfile|editUser') (After reviewing search results, assuming a relevant file like '/path/to/UserProfileService.java' was found) Okay, \`/path/to/UserProfileService.java\` seems like the most relevant file. I'll read its content to understand how updates are handled. -[tool_call: read_file for absolute_path '/path/to/UserProfileService.java'] +(I'll read the file: read_file on '/path/to/UserProfileService.java') (After reading the file) It appears the \`updateUserProfile\` method in \`UserProfileService.java\` is responsible for this. It expects a user ID and a \`UserProfileDTO\` object... @@ -163,7 +164,7 @@ It appears the \`updateUserProfile\` method in \`UserProfileService.java\` is re user: Where are all the 'app.config' files in this project? I need to check their settings. model: -[tool_call: glob for pattern '**/app.config'] +(I'll find all matching files: glob on '**/app.config') (Assuming GlobTool returns a list of paths like ['/path/to/moduleA/app.config', '/path/to/moduleB/app.config']) I found the following 'app.config' files: - /path/to/moduleA/app.config @@ -243,6 +244,7 @@ When requested to perform tasks like fixing bugs, adding features, refactoring, - **File Paths:** Always use absolute paths when referring to files with tools like 'read_file' or 'write_file'. Relative paths are not supported. You must provide an absolute path. - **Parallelism:** Execute multiple independent tool calls in parallel when feasible (i.e. searching the codebase). - **Command Execution:** Use the 'run_shell_command' tool for running shell commands, remembering the safety rule to explain modifying commands first. +- **Tool Calling (Critical):** Never emit pseudo tool-call markers (e.g. "tool_call: ...") in normal text. When you need to use a tool, call it using the tool-calling mechanism. - **Background Processes:** Use background processes (via \`&\`) for commands that are unlikely to stop on their own, e.g. \`node server.js &\`. If unsure, ask the user. - **Interactive Commands:** Try to avoid shell commands that are likely to require user interaction (e.g. \`git rebase -i\`). Use non-interactive versions of commands (e.g. \`npm init -y\` instead of \`npm init\`) when available, and otherwise remind the user that interactive shell commands are not supported and may cause hangs until canceled by the user. - **Remembering Facts:** Use the 'save_memory' tool to remember specific, *user-related* facts or preferences when the user explicitly asks, or when they state a clear, concise piece of information that would help personalize or streamline *your future interactions with them* (e.g., preferred coding style, common project paths they use, personal tool aliases). This tool is for user-specific information that should persist across sessions. Do *not* use it for general project context or information that belongs in project-specific \`GEMINI.md\` files. If unsure whether to save something, you can ask the user, "Should I remember that for you?" @@ -287,24 +289,24 @@ model: true user: list files here. -model: [tool_call: list_directory for path '.'] +model: I'll use the list_directory tool to list files in '.'. user: start the server implemented in server.js -model: [tool_call: run_shell_command for 'node server.js &' because it must run in the background] +model: I'll run \`node server.js &\` using the run_shell_command tool (it must run in the background). user: Refactor the auth logic in src/auth.py to use the requests library instead of urllib. model: Okay, I can refactor 'src/auth.py'. First, I'll analyze the code and check for a test safety net before planning any changes. -[tool_call: glob for path 'tests/test_auth.py'] -[tool_call: read_file for absolute_path '/path/to/tests/test_auth.py'] +(I'll search for tests: glob on 'tests/test_auth.py') +(I'll read the test file: read_file on '/path/to/tests/test_auth.py') (After analysis) Great, 'tests/test_auth.py' exists and covers the core authentication logic. With this safety net in place, I can safely plan the refactoring. I'll also confirm 'requests' is a dependency. -[tool_call: read_file for absolute_path '/path/to/requirements.txt'] +(I'll check dependencies: read_file on '/path/to/requirements.txt') (After analysis) Looks good, 'requests' is available. @@ -317,9 +319,9 @@ Here's the plan: Should I proceed? user: Yes model: -[tool_call: write_file or replace to apply the refactoring to 'src/auth.py'] +(I'll apply the refactor using write_file or replace on 'src/auth.py') Refactoring complete. Running verification... -[tool_call: run_shell_command for 'ruff check src/auth.py && pytest'] +(I'll run verification using run_shell_command: \`ruff check src/auth.py && pytest\`) (After verification passes) All checks passed. This is a stable checkpoint. Would you like me to write a commit message and commit these changes? @@ -334,23 +336,23 @@ model: I can run \`rm -rf ./temp\`. This will permanently delete the directory a user: Write tests for someFile.ts model: Okay, I can write those tests. First, I'll read \`someFile.ts\` to understand its functionality. -[tool_call: read_file for absolute_path '/path/to/someFile.ts' or use glob to find \`someFile.ts\` if its location is unknown] +(I'll read the file: read_file on '/path/to/someFile.ts', or use glob if its location is unknown) Now I'll look for existing or related test files to understand current testing conventions and dependencies. -[tool_call: read_many_files for paths ['**/*.test.ts', 'src/**/*.spec.ts'] assuming someFile.ts is in the src directory] +(I'll read related tests: read_many_files on ['**/*.test.ts', 'src/**/*.spec.ts']) (After reviewing existing tests and the file content) -[tool_call: write_file to create /path/to/someFile.test.ts with the test code] +(I'll write the new test file: write_file on '/path/to/someFile.test.ts') I've written the tests. Now I'll run the project's test command to verify them. -[tool_call: run_shell_command for 'npm run test'] +(I'll run tests using run_shell_command: \`npm run test\`) user: How do I update the user's profile information in this system? model: I'm not immediately sure how user profile information is updated. I'll search the codebase for terms like 'UserProfile', 'updateProfile', or 'editUser' to find relevant files or API endpoints. -[tool_call: search_file_content for pattern 'UserProfile|updateProfile|editUser'] +(I'll search the codebase: search_file_content on 'UserProfile|updateProfile|editUser') (After reviewing search results, assuming a relevant file like '/path/to/UserProfileService.java' was found) Okay, \`/path/to/UserProfileService.java\` seems like the most relevant file. I'll read its content to understand how updates are handled. -[tool_call: read_file for absolute_path '/path/to/UserProfileService.java'] +(I'll read the file: read_file on '/path/to/UserProfileService.java') (After reading the file) It appears the \`updateUserProfile\` method in \`UserProfileService.java\` is responsible for this. It expects a user ID and a \`UserProfileDTO\` object... @@ -358,7 +360,7 @@ It appears the \`updateUserProfile\` method in \`UserProfileService.java\` is re user: Where are all the 'app.config' files in this project? I need to check their settings. model: -[tool_call: glob for pattern '**/app.config'] +(I'll find all matching files: glob on '**/app.config') (Assuming GlobTool returns a list of paths like ['/path/to/moduleA/app.config', '/path/to/moduleB/app.config']) I found the following 'app.config' files: - /path/to/moduleA/app.config @@ -433,6 +435,7 @@ When requested to perform tasks like fixing bugs, adding features, refactoring, - **File Paths:** Always use absolute paths when referring to files with tools like 'read_file' or 'write_file'. Relative paths are not supported. You must provide an absolute path. - **Parallelism:** Execute multiple independent tool calls in parallel when feasible (i.e. searching the codebase). - **Command Execution:** Use the 'run_shell_command' tool for running shell commands, remembering the safety rule to explain modifying commands first. +- **Tool Calling (Critical):** Never emit pseudo tool-call markers (e.g. "tool_call: ...") in normal text. When you need to use a tool, call it using the tool-calling mechanism. - **Background Processes:** Use background processes (via \`&\`) for commands that are unlikely to stop on their own, e.g. \`node server.js &\`. If unsure, ask the user. - **Interactive Commands:** Try to avoid shell commands that are likely to require user interaction (e.g. \`git rebase -i\`). Use non-interactive versions of commands (e.g. \`npm init -y\` instead of \`npm init\`) when available, and otherwise remind the user that interactive shell commands are not supported and may cause hangs until canceled by the user. - **Remembering Facts:** Use the 'save_memory' tool to remember specific, *user-related* facts or preferences when the user explicitly asks, or when they state a clear, concise piece of information that would help personalize or streamline *your future interactions with them* (e.g., preferred coding style, common project paths they use, personal tool aliases). This tool is for user-specific information that should persist across sessions. Do *not* use it for general project context or information that belongs in project-specific \`GEMINI.md\` files. If unsure whether to save something, you can ask the user, "Should I remember that for you?" @@ -462,24 +465,24 @@ model: true user: list files here. -model: [tool_call: list_directory for path '.'] +model: I'll use the list_directory tool to list files in '.'. user: start the server implemented in server.js -model: [tool_call: run_shell_command for 'node server.js &' because it must run in the background] +model: I'll run \`node server.js &\` using the run_shell_command tool (it must run in the background). user: Refactor the auth logic in src/auth.py to use the requests library instead of urllib. model: Okay, I can refactor 'src/auth.py'. First, I'll analyze the code and check for a test safety net before planning any changes. -[tool_call: glob for path 'tests/test_auth.py'] -[tool_call: read_file for absolute_path '/path/to/tests/test_auth.py'] +(I'll search for tests: glob on 'tests/test_auth.py') +(I'll read the test file: read_file on '/path/to/tests/test_auth.py') (After analysis) Great, 'tests/test_auth.py' exists and covers the core authentication logic. With this safety net in place, I can safely plan the refactoring. I'll also confirm 'requests' is a dependency. -[tool_call: read_file for absolute_path '/path/to/requirements.txt'] +(I'll check dependencies: read_file on '/path/to/requirements.txt') (After analysis) Looks good, 'requests' is available. @@ -492,9 +495,9 @@ Here's the plan: Should I proceed? user: Yes model: -[tool_call: write_file or replace to apply the refactoring to 'src/auth.py'] +(I'll apply the refactor using write_file or replace on 'src/auth.py') Refactoring complete. Running verification... -[tool_call: run_shell_command for 'ruff check src/auth.py && pytest'] +(I'll run verification using run_shell_command: \`ruff check src/auth.py && pytest\`) (After verification passes) All checks passed. This is a stable checkpoint. @@ -509,23 +512,23 @@ model: I can run \`rm -rf ./temp\`. This will permanently delete the directory a user: Write tests for someFile.ts model: Okay, I can write those tests. First, I'll read \`someFile.ts\` to understand its functionality. -[tool_call: read_file for absolute_path '/path/to/someFile.ts' or use glob to find \`someFile.ts\` if its location is unknown] +(I'll read the file: read_file on '/path/to/someFile.ts', or use glob if its location is unknown) Now I'll look for existing or related test files to understand current testing conventions and dependencies. -[tool_call: read_many_files for paths ['**/*.test.ts', 'src/**/*.spec.ts'] assuming someFile.ts is in the src directory] +(I'll read related tests: read_many_files on ['**/*.test.ts', 'src/**/*.spec.ts']) (After reviewing existing tests and the file content) -[tool_call: write_file to create /path/to/someFile.test.ts with the test code] +(I'll write the new test file: write_file on '/path/to/someFile.test.ts') I've written the tests. Now I'll run the project's test command to verify them. -[tool_call: run_shell_command for 'npm run test'] +(I'll run tests using run_shell_command: \`npm run test\`) user: How do I update the user's profile information in this system? model: I'm not immediately sure how user profile information is updated. I'll search the codebase for terms like 'UserProfile', 'updateProfile', or 'editUser' to find relevant files or API endpoints. -[tool_call: search_file_content for pattern 'UserProfile|updateProfile|editUser'] +(I'll search the codebase: search_file_content on 'UserProfile|updateProfile|editUser') (After reviewing search results, assuming a relevant file like '/path/to/UserProfileService.java' was found) Okay, \`/path/to/UserProfileService.java\` seems like the most relevant file. I'll read its content to understand how updates are handled. -[tool_call: read_file for absolute_path '/path/to/UserProfileService.java'] +(I'll read the file: read_file on '/path/to/UserProfileService.java') (After reading the file) It appears the \`updateUserProfile\` method in \`UserProfileService.java\` is responsible for this. It expects a user ID and a \`UserProfileDTO\` object... @@ -533,7 +536,7 @@ It appears the \`updateUserProfile\` method in \`UserProfileService.java\` is re user: Where are all the 'app.config' files in this project? I need to check their settings. model: -[tool_call: glob for pattern '**/app.config'] +(I'll find all matching files: glob on '**/app.config') (Assuming GlobTool returns a list of paths like ['/path/to/moduleA/app.config', '/path/to/moduleB/app.config']) I found the following 'app.config' files: - /path/to/moduleA/app.config @@ -608,6 +611,7 @@ When requested to perform tasks like fixing bugs, adding features, refactoring, - **File Paths:** Always use absolute paths when referring to files with tools like 'read_file' or 'write_file'. Relative paths are not supported. You must provide an absolute path. - **Parallelism:** Execute multiple independent tool calls in parallel when feasible (i.e. searching the codebase). - **Command Execution:** Use the 'run_shell_command' tool for running shell commands, remembering the safety rule to explain modifying commands first. +- **Tool Calling (Critical):** Never emit pseudo tool-call markers (e.g. "tool_call: ...") in normal text. When you need to use a tool, call it using the tool-calling mechanism. - **Background Processes:** Use background processes (via \`&\`) for commands that are unlikely to stop on their own, e.g. \`node server.js &\`. If unsure, ask the user. - **Interactive Commands:** Try to avoid shell commands that are likely to require user interaction (e.g. \`git rebase -i\`). Use non-interactive versions of commands (e.g. \`npm init -y\` instead of \`npm init\`) when available, and otherwise remind the user that interactive shell commands are not supported and may cause hangs until canceled by the user. - **Remembering Facts:** Use the 'save_memory' tool to remember specific, *user-related* facts or preferences when the user explicitly asks, or when they state a clear, concise piece of information that would help personalize or streamline *your future interactions with them* (e.g., preferred coding style, common project paths they use, personal tool aliases). This tool is for user-specific information that should persist across sessions. Do *not* use it for general project context or information that belongs in project-specific \`GEMINI.md\` files. If unsure whether to save something, you can ask the user, "Should I remember that for you?" @@ -637,24 +641,24 @@ model: true user: list files here. -model: [tool_call: list_directory for path '.'] +model: I'll use the list_directory tool to list files in '.'. user: start the server implemented in server.js -model: [tool_call: run_shell_command for 'node server.js &' because it must run in the background] +model: I'll run \`node server.js &\` using the run_shell_command tool (it must run in the background). user: Refactor the auth logic in src/auth.py to use the requests library instead of urllib. model: Okay, I can refactor 'src/auth.py'. First, I'll analyze the code and check for a test safety net before planning any changes. -[tool_call: glob for path 'tests/test_auth.py'] -[tool_call: read_file for absolute_path '/path/to/tests/test_auth.py'] +(I'll search for tests: glob on 'tests/test_auth.py') +(I'll read the test file: read_file on '/path/to/tests/test_auth.py') (After analysis) Great, 'tests/test_auth.py' exists and covers the core authentication logic. With this safety net in place, I can safely plan the refactoring. I'll also confirm 'requests' is a dependency. -[tool_call: read_file for absolute_path '/path/to/requirements.txt'] +(I'll check dependencies: read_file on '/path/to/requirements.txt') (After analysis) Looks good, 'requests' is available. @@ -667,9 +671,9 @@ Here's the plan: Should I proceed? user: Yes model: -[tool_call: write_file or replace to apply the refactoring to 'src/auth.py'] +(I'll apply the refactor using write_file or replace on 'src/auth.py') Refactoring complete. Running verification... -[tool_call: run_shell_command for 'ruff check src/auth.py && pytest'] +(I'll run verification using run_shell_command: \`ruff check src/auth.py && pytest\`) (After verification passes) All checks passed. This is a stable checkpoint. @@ -684,23 +688,23 @@ model: I can run \`rm -rf ./temp\`. This will permanently delete the directory a user: Write tests for someFile.ts model: Okay, I can write those tests. First, I'll read \`someFile.ts\` to understand its functionality. -[tool_call: read_file for absolute_path '/path/to/someFile.ts' or use glob to find \`someFile.ts\` if its location is unknown] +(I'll read the file: read_file on '/path/to/someFile.ts', or use glob if its location is unknown) Now I'll look for existing or related test files to understand current testing conventions and dependencies. -[tool_call: read_many_files for paths ['**/*.test.ts', 'src/**/*.spec.ts'] assuming someFile.ts is in the src directory] +(I'll read related tests: read_many_files on ['**/*.test.ts', 'src/**/*.spec.ts']) (After reviewing existing tests and the file content) -[tool_call: write_file to create /path/to/someFile.test.ts with the test code] +(I'll write the new test file: write_file on '/path/to/someFile.test.ts') I've written the tests. Now I'll run the project's test command to verify them. -[tool_call: run_shell_command for 'npm run test'] +(I'll run tests using run_shell_command: \`npm run test\`) user: How do I update the user's profile information in this system? model: I'm not immediately sure how user profile information is updated. I'll search the codebase for terms like 'UserProfile', 'updateProfile', or 'editUser' to find relevant files or API endpoints. -[tool_call: search_file_content for pattern 'UserProfile|updateProfile|editUser'] +(I'll search the codebase: search_file_content on 'UserProfile|updateProfile|editUser') (After reviewing search results, assuming a relevant file like '/path/to/UserProfileService.java' was found) Okay, \`/path/to/UserProfileService.java\` seems like the most relevant file. I'll read its content to understand how updates are handled. -[tool_call: read_file for absolute_path '/path/to/UserProfileService.java'] +(I'll read the file: read_file on '/path/to/UserProfileService.java') (After reading the file) It appears the \`updateUserProfile\` method in \`UserProfileService.java\` is responsible for this. It expects a user ID and a \`UserProfileDTO\` object... @@ -708,7 +712,7 @@ It appears the \`updateUserProfile\` method in \`UserProfileService.java\` is re user: Where are all the 'app.config' files in this project? I need to check their settings. model: -[tool_call: glob for pattern '**/app.config'] +(I'll find all matching files: glob on '**/app.config') (Assuming GlobTool returns a list of paths like ['/path/to/moduleA/app.config', '/path/to/moduleB/app.config']) I found the following 'app.config' files: - /path/to/moduleA/app.config @@ -783,6 +787,7 @@ When requested to perform tasks like fixing bugs, adding features, refactoring, - **File Paths:** Always use absolute paths when referring to files with tools like 'read_file' or 'write_file'. Relative paths are not supported. You must provide an absolute path. - **Parallelism:** Execute multiple independent tool calls in parallel when feasible (i.e. searching the codebase). - **Command Execution:** Use the 'run_shell_command' tool for running shell commands, remembering the safety rule to explain modifying commands first. +- **Tool Calling (Critical):** Never emit pseudo tool-call markers (e.g. "tool_call: ...") in normal text. When you need to use a tool, call it using the tool-calling mechanism. - **Background Processes:** Use background processes (via \`&\`) for commands that are unlikely to stop on their own, e.g. \`node server.js &\`. If unsure, ask the user. - **Interactive Commands:** Try to avoid shell commands that are likely to require user interaction (e.g. \`git rebase -i\`). Use non-interactive versions of commands (e.g. \`npm init -y\` instead of \`npm init\`) when available, and otherwise remind the user that interactive shell commands are not supported and may cause hangs until canceled by the user. - **Remembering Facts:** Use the 'save_memory' tool to remember specific, *user-related* facts or preferences when the user explicitly asks, or when they state a clear, concise piece of information that would help personalize or streamline *your future interactions with them* (e.g., preferred coding style, common project paths they use, personal tool aliases). This tool is for user-specific information that should persist across sessions. Do *not* use it for general project context or information that belongs in project-specific \`GEMINI.md\` files. If unsure whether to save something, you can ask the user, "Should I remember that for you?" @@ -812,24 +817,24 @@ model: true user: list files here. -model: [tool_call: list_directory for path '.'] +model: I'll use the list_directory tool to list files in '.'. user: start the server implemented in server.js -model: [tool_call: run_shell_command for 'node server.js &' because it must run in the background] +model: I'll run \`node server.js &\` using the run_shell_command tool (it must run in the background). user: Refactor the auth logic in src/auth.py to use the requests library instead of urllib. model: Okay, I can refactor 'src/auth.py'. First, I'll analyze the code and check for a test safety net before planning any changes. -[tool_call: glob for path 'tests/test_auth.py'] -[tool_call: read_file for absolute_path '/path/to/tests/test_auth.py'] +(I'll search for tests: glob on 'tests/test_auth.py') +(I'll read the test file: read_file on '/path/to/tests/test_auth.py') (After analysis) Great, 'tests/test_auth.py' exists and covers the core authentication logic. With this safety net in place, I can safely plan the refactoring. I'll also confirm 'requests' is a dependency. -[tool_call: read_file for absolute_path '/path/to/requirements.txt'] +(I'll check dependencies: read_file on '/path/to/requirements.txt') (After analysis) Looks good, 'requests' is available. @@ -842,9 +847,9 @@ Here's the plan: Should I proceed? user: Yes model: -[tool_call: write_file or replace to apply the refactoring to 'src/auth.py'] +(I'll apply the refactor using write_file or replace on 'src/auth.py') Refactoring complete. Running verification... -[tool_call: run_shell_command for 'ruff check src/auth.py && pytest'] +(I'll run verification using run_shell_command: \`ruff check src/auth.py && pytest\`) (After verification passes) All checks passed. This is a stable checkpoint. @@ -859,23 +864,23 @@ model: I can run \`rm -rf ./temp\`. This will permanently delete the directory a user: Write tests for someFile.ts model: Okay, I can write those tests. First, I'll read \`someFile.ts\` to understand its functionality. -[tool_call: read_file for absolute_path '/path/to/someFile.ts' or use glob to find \`someFile.ts\` if its location is unknown] +(I'll read the file: read_file on '/path/to/someFile.ts', or use glob if its location is unknown) Now I'll look for existing or related test files to understand current testing conventions and dependencies. -[tool_call: read_many_files for paths ['**/*.test.ts', 'src/**/*.spec.ts'] assuming someFile.ts is in the src directory] +(I'll read related tests: read_many_files on ['**/*.test.ts', 'src/**/*.spec.ts']) (After reviewing existing tests and the file content) -[tool_call: write_file to create /path/to/someFile.test.ts with the test code] +(I'll write the new test file: write_file on '/path/to/someFile.test.ts') I've written the tests. Now I'll run the project's test command to verify them. -[tool_call: run_shell_command for 'npm run test'] +(I'll run tests using run_shell_command: \`npm run test\`) user: How do I update the user's profile information in this system? model: I'm not immediately sure how user profile information is updated. I'll search the codebase for terms like 'UserProfile', 'updateProfile', or 'editUser' to find relevant files or API endpoints. -[tool_call: search_file_content for pattern 'UserProfile|updateProfile|editUser'] +(I'll search the codebase: search_file_content on 'UserProfile|updateProfile|editUser') (After reviewing search results, assuming a relevant file like '/path/to/UserProfileService.java' was found) Okay, \`/path/to/UserProfileService.java\` seems like the most relevant file. I'll read its content to understand how updates are handled. -[tool_call: read_file for absolute_path '/path/to/UserProfileService.java'] +(I'll read the file: read_file on '/path/to/UserProfileService.java') (After reading the file) It appears the \`updateUserProfile\` method in \`UserProfileService.java\` is responsible for this. It expects a user ID and a \`UserProfileDTO\` object... @@ -883,7 +888,7 @@ It appears the \`updateUserProfile\` method in \`UserProfileService.java\` is re user: Where are all the 'app.config' files in this project? I need to check their settings. model: -[tool_call: glob for pattern '**/app.config'] +(I'll find all matching files: glob on '**/app.config') (Assuming GlobTool returns a list of paths like ['/path/to/moduleA/app.config', '/path/to/moduleB/app.config']) I found the following 'app.config' files: - /path/to/moduleA/app.config @@ -958,6 +963,7 @@ When requested to perform tasks like fixing bugs, adding features, refactoring, - **File Paths:** Always use absolute paths when referring to files with tools like 'read_file' or 'write_file'. Relative paths are not supported. You must provide an absolute path. - **Parallelism:** Execute multiple independent tool calls in parallel when feasible (i.e. searching the codebase). - **Command Execution:** Use the 'run_shell_command' tool for running shell commands, remembering the safety rule to explain modifying commands first. +- **Tool Calling (Critical):** Never emit pseudo tool-call markers (e.g. "tool_call: ...") in normal text. When you need to use a tool, call it using the tool-calling mechanism. - **Background Processes:** Use background processes (via \`&\`) for commands that are unlikely to stop on their own, e.g. \`node server.js &\`. If unsure, ask the user. - **Interactive Commands:** Try to avoid shell commands that are likely to require user interaction (e.g. \`git rebase -i\`). Use non-interactive versions of commands (e.g. \`npm init -y\` instead of \`npm init\`) when available, and otherwise remind the user that interactive shell commands are not supported and may cause hangs until canceled by the user. - **Remembering Facts:** Use the 'save_memory' tool to remember specific, *user-related* facts or preferences when the user explicitly asks, or when they state a clear, concise piece of information that would help personalize or streamline *your future interactions with them* (e.g., preferred coding style, common project paths they use, personal tool aliases). This tool is for user-specific information that should persist across sessions. Do *not* use it for general project context or information that belongs in project-specific \`GEMINI.md\` files. If unsure whether to save something, you can ask the user, "Should I remember that for you?" @@ -987,24 +993,24 @@ model: true user: list files here. -model: [tool_call: list_directory for path '.'] +model: I'll use the list_directory tool to list files in '.'. user: start the server implemented in server.js -model: [tool_call: run_shell_command for 'node server.js &' because it must run in the background] +model: I'll run \`node server.js &\` using the run_shell_command tool (it must run in the background). user: Refactor the auth logic in src/auth.py to use the requests library instead of urllib. model: Okay, I can refactor 'src/auth.py'. First, I'll analyze the code and check for a test safety net before planning any changes. -[tool_call: glob for path 'tests/test_auth.py'] -[tool_call: read_file for absolute_path '/path/to/tests/test_auth.py'] +(I'll search for tests: glob on 'tests/test_auth.py') +(I'll read the test file: read_file on '/path/to/tests/test_auth.py') (After analysis) Great, 'tests/test_auth.py' exists and covers the core authentication logic. With this safety net in place, I can safely plan the refactoring. I'll also confirm 'requests' is a dependency. -[tool_call: read_file for absolute_path '/path/to/requirements.txt'] +(I'll check dependencies: read_file on '/path/to/requirements.txt') (After analysis) Looks good, 'requests' is available. @@ -1017,9 +1023,9 @@ Here's the plan: Should I proceed? user: Yes model: -[tool_call: write_file or replace to apply the refactoring to 'src/auth.py'] +(I'll apply the refactor using write_file or replace on 'src/auth.py') Refactoring complete. Running verification... -[tool_call: run_shell_command for 'ruff check src/auth.py && pytest'] +(I'll run verification using run_shell_command: \`ruff check src/auth.py && pytest\`) (After verification passes) All checks passed. This is a stable checkpoint. @@ -1034,23 +1040,23 @@ model: I can run \`rm -rf ./temp\`. This will permanently delete the directory a user: Write tests for someFile.ts model: Okay, I can write those tests. First, I'll read \`someFile.ts\` to understand its functionality. -[tool_call: read_file for absolute_path '/path/to/someFile.ts' or use glob to find \`someFile.ts\` if its location is unknown] +(I'll read the file: read_file on '/path/to/someFile.ts', or use glob if its location is unknown) Now I'll look for existing or related test files to understand current testing conventions and dependencies. -[tool_call: read_many_files for paths ['**/*.test.ts', 'src/**/*.spec.ts'] assuming someFile.ts is in the src directory] +(I'll read related tests: read_many_files on ['**/*.test.ts', 'src/**/*.spec.ts']) (After reviewing existing tests and the file content) -[tool_call: write_file to create /path/to/someFile.test.ts with the test code] +(I'll write the new test file: write_file on '/path/to/someFile.test.ts') I've written the tests. Now I'll run the project's test command to verify them. -[tool_call: run_shell_command for 'npm run test'] +(I'll run tests using run_shell_command: \`npm run test\`) user: How do I update the user's profile information in this system? model: I'm not immediately sure how user profile information is updated. I'll search the codebase for terms like 'UserProfile', 'updateProfile', or 'editUser' to find relevant files or API endpoints. -[tool_call: search_file_content for pattern 'UserProfile|updateProfile|editUser'] +(I'll search the codebase: search_file_content on 'UserProfile|updateProfile|editUser') (After reviewing search results, assuming a relevant file like '/path/to/UserProfileService.java' was found) Okay, \`/path/to/UserProfileService.java\` seems like the most relevant file. I'll read its content to understand how updates are handled. -[tool_call: read_file for absolute_path '/path/to/UserProfileService.java'] +(I'll read the file: read_file on '/path/to/UserProfileService.java') (After reading the file) It appears the \`updateUserProfile\` method in \`UserProfileService.java\` is responsible for this. It expects a user ID and a \`UserProfileDTO\` object... @@ -1058,7 +1064,7 @@ It appears the \`updateUserProfile\` method in \`UserProfileService.java\` is re user: Where are all the 'app.config' files in this project? I need to check their settings. model: -[tool_call: glob for pattern '**/app.config'] +(I'll find all matching files: glob on '**/app.config') (Assuming GlobTool returns a list of paths like ['/path/to/moduleA/app.config', '/path/to/moduleB/app.config']) I found the following 'app.config' files: - /path/to/moduleA/app.config @@ -1133,6 +1139,7 @@ When requested to perform tasks like fixing bugs, adding features, refactoring, - **File Paths:** Always use absolute paths when referring to files with tools like 'read_file' or 'write_file'. Relative paths are not supported. You must provide an absolute path. - **Parallelism:** Execute multiple independent tool calls in parallel when feasible (i.e. searching the codebase). - **Command Execution:** Use the 'run_shell_command' tool for running shell commands, remembering the safety rule to explain modifying commands first. +- **Tool Calling (Critical):** Never emit pseudo tool-call markers (e.g. "tool_call: ...") in normal text. When you need to use a tool, call it using the tool-calling mechanism. - **Background Processes:** Use background processes (via \`&\`) for commands that are unlikely to stop on their own, e.g. \`node server.js &\`. If unsure, ask the user. - **Interactive Commands:** Try to avoid shell commands that are likely to require user interaction (e.g. \`git rebase -i\`). Use non-interactive versions of commands (e.g. \`npm init -y\` instead of \`npm init\`) when available, and otherwise remind the user that interactive shell commands are not supported and may cause hangs until canceled by the user. - **Remembering Facts:** Use the 'save_memory' tool to remember specific, *user-related* facts or preferences when the user explicitly asks, or when they state a clear, concise piece of information that would help personalize or streamline *your future interactions with them* (e.g., preferred coding style, common project paths they use, personal tool aliases). This tool is for user-specific information that should persist across sessions. Do *not* use it for general project context or information that belongs in project-specific \`GEMINI.md\` files. If unsure whether to save something, you can ask the user, "Should I remember that for you?" @@ -1162,24 +1169,24 @@ model: true user: list files here. -model: [tool_call: list_directory for path '.'] +model: I'll use the list_directory tool to list files in '.'. user: start the server implemented in server.js -model: [tool_call: run_shell_command for 'node server.js &' because it must run in the background] +model: I'll run \`node server.js &\` using the run_shell_command tool (it must run in the background). user: Refactor the auth logic in src/auth.py to use the requests library instead of urllib. model: Okay, I can refactor 'src/auth.py'. First, I'll analyze the code and check for a test safety net before planning any changes. -[tool_call: glob for path 'tests/test_auth.py'] -[tool_call: read_file for absolute_path '/path/to/tests/test_auth.py'] +(I'll search for tests: glob on 'tests/test_auth.py') +(I'll read the test file: read_file on '/path/to/tests/test_auth.py') (After analysis) Great, 'tests/test_auth.py' exists and covers the core authentication logic. With this safety net in place, I can safely plan the refactoring. I'll also confirm 'requests' is a dependency. -[tool_call: read_file for absolute_path '/path/to/requirements.txt'] +(I'll check dependencies: read_file on '/path/to/requirements.txt') (After analysis) Looks good, 'requests' is available. @@ -1192,9 +1199,9 @@ Here's the plan: Should I proceed? user: Yes model: -[tool_call: write_file or replace to apply the refactoring to 'src/auth.py'] +(I'll apply the refactor using write_file or replace on 'src/auth.py') Refactoring complete. Running verification... -[tool_call: run_shell_command for 'ruff check src/auth.py && pytest'] +(I'll run verification using run_shell_command: \`ruff check src/auth.py && pytest\`) (After verification passes) All checks passed. This is a stable checkpoint. @@ -1209,23 +1216,23 @@ model: I can run \`rm -rf ./temp\`. This will permanently delete the directory a user: Write tests for someFile.ts model: Okay, I can write those tests. First, I'll read \`someFile.ts\` to understand its functionality. -[tool_call: read_file for absolute_path '/path/to/someFile.ts' or use glob to find \`someFile.ts\` if its location is unknown] +(I'll read the file: read_file on '/path/to/someFile.ts', or use glob if its location is unknown) Now I'll look for existing or related test files to understand current testing conventions and dependencies. -[tool_call: read_many_files for paths ['**/*.test.ts', 'src/**/*.spec.ts'] assuming someFile.ts is in the src directory] +(I'll read related tests: read_many_files on ['**/*.test.ts', 'src/**/*.spec.ts']) (After reviewing existing tests and the file content) -[tool_call: write_file to create /path/to/someFile.test.ts with the test code] +(I'll write the new test file: write_file on '/path/to/someFile.test.ts') I've written the tests. Now I'll run the project's test command to verify them. -[tool_call: run_shell_command for 'npm run test'] +(I'll run tests using run_shell_command: \`npm run test\`) user: How do I update the user's profile information in this system? model: I'm not immediately sure how user profile information is updated. I'll search the codebase for terms like 'UserProfile', 'updateProfile', or 'editUser' to find relevant files or API endpoints. -[tool_call: search_file_content for pattern 'UserProfile|updateProfile|editUser'] +(I'll search the codebase: search_file_content on 'UserProfile|updateProfile|editUser') (After reviewing search results, assuming a relevant file like '/path/to/UserProfileService.java' was found) Okay, \`/path/to/UserProfileService.java\` seems like the most relevant file. I'll read its content to understand how updates are handled. -[tool_call: read_file for absolute_path '/path/to/UserProfileService.java'] +(I'll read the file: read_file on '/path/to/UserProfileService.java') (After reading the file) It appears the \`updateUserProfile\` method in \`UserProfileService.java\` is responsible for this. It expects a user ID and a \`UserProfileDTO\` object... @@ -1233,7 +1240,7 @@ It appears the \`updateUserProfile\` method in \`UserProfileService.java\` is re user: Where are all the 'app.config' files in this project? I need to check their settings. model: -[tool_call: glob for pattern '**/app.config'] +(I'll find all matching files: glob on '**/app.config') (Assuming GlobTool returns a list of paths like ['/path/to/moduleA/app.config', '/path/to/moduleB/app.config']) I found the following 'app.config' files: - /path/to/moduleA/app.config @@ -1308,6 +1315,7 @@ When requested to perform tasks like fixing bugs, adding features, refactoring, - **File Paths:** Always use absolute paths when referring to files with tools like 'read_file' or 'write_file'. Relative paths are not supported. You must provide an absolute path. - **Parallelism:** Execute multiple independent tool calls in parallel when feasible (i.e. searching the codebase). - **Command Execution:** Use the 'run_shell_command' tool for running shell commands, remembering the safety rule to explain modifying commands first. +- **Tool Calling (Critical):** Never emit pseudo tool-call markers (e.g. "tool_call: ...") in normal text. When you need to use a tool, call it using the tool-calling mechanism. - **Background Processes:** Use background processes (via \`&\`) for commands that are unlikely to stop on their own, e.g. \`node server.js &\`. If unsure, ask the user. - **Interactive Commands:** Try to avoid shell commands that are likely to require user interaction (e.g. \`git rebase -i\`). Use non-interactive versions of commands (e.g. \`npm init -y\` instead of \`npm init\`) when available, and otherwise remind the user that interactive shell commands are not supported and may cause hangs until canceled by the user. - **Remembering Facts:** Use the 'save_memory' tool to remember specific, *user-related* facts or preferences when the user explicitly asks, or when they state a clear, concise piece of information that would help personalize or streamline *your future interactions with them* (e.g., preferred coding style, common project paths they use, personal tool aliases). This tool is for user-specific information that should persist across sessions. Do *not* use it for general project context or information that belongs in project-specific \`GEMINI.md\` files. If unsure whether to save something, you can ask the user, "Should I remember that for you?" @@ -1337,24 +1345,24 @@ model: true user: list files here. -model: [tool_call: list_directory for path '.'] +model: I'll use the list_directory tool to list files in '.'. user: start the server implemented in server.js -model: [tool_call: run_shell_command for 'node server.js &' because it must run in the background] +model: I'll run \`node server.js &\` using the run_shell_command tool (it must run in the background). user: Refactor the auth logic in src/auth.py to use the requests library instead of urllib. model: Okay, I can refactor 'src/auth.py'. First, I'll analyze the code and check for a test safety net before planning any changes. -[tool_call: glob for path 'tests/test_auth.py'] -[tool_call: read_file for absolute_path '/path/to/tests/test_auth.py'] +(I'll search for tests: glob on 'tests/test_auth.py') +(I'll read the test file: read_file on '/path/to/tests/test_auth.py') (After analysis) Great, 'tests/test_auth.py' exists and covers the core authentication logic. With this safety net in place, I can safely plan the refactoring. I'll also confirm 'requests' is a dependency. -[tool_call: read_file for absolute_path '/path/to/requirements.txt'] +(I'll check dependencies: read_file on '/path/to/requirements.txt') (After analysis) Looks good, 'requests' is available. @@ -1367,9 +1375,9 @@ Here's the plan: Should I proceed? user: Yes model: -[tool_call: write_file or replace to apply the refactoring to 'src/auth.py'] +(I'll apply the refactor using write_file or replace on 'src/auth.py') Refactoring complete. Running verification... -[tool_call: run_shell_command for 'ruff check src/auth.py && pytest'] +(I'll run verification using run_shell_command: \`ruff check src/auth.py && pytest\`) (After verification passes) All checks passed. This is a stable checkpoint. @@ -1384,23 +1392,23 @@ model: I can run \`rm -rf ./temp\`. This will permanently delete the directory a user: Write tests for someFile.ts model: Okay, I can write those tests. First, I'll read \`someFile.ts\` to understand its functionality. -[tool_call: read_file for absolute_path '/path/to/someFile.ts' or use glob to find \`someFile.ts\` if its location is unknown] +(I'll read the file: read_file on '/path/to/someFile.ts', or use glob if its location is unknown) Now I'll look for existing or related test files to understand current testing conventions and dependencies. -[tool_call: read_many_files for paths ['**/*.test.ts', 'src/**/*.spec.ts'] assuming someFile.ts is in the src directory] +(I'll read related tests: read_many_files on ['**/*.test.ts', 'src/**/*.spec.ts']) (After reviewing existing tests and the file content) -[tool_call: write_file to create /path/to/someFile.test.ts with the test code] +(I'll write the new test file: write_file on '/path/to/someFile.test.ts') I've written the tests. Now I'll run the project's test command to verify them. -[tool_call: run_shell_command for 'npm run test'] +(I'll run tests using run_shell_command: \`npm run test\`) user: How do I update the user's profile information in this system? model: I'm not immediately sure how user profile information is updated. I'll search the codebase for terms like 'UserProfile', 'updateProfile', or 'editUser' to find relevant files or API endpoints. -[tool_call: search_file_content for pattern 'UserProfile|updateProfile|editUser'] +(I'll search the codebase: search_file_content on 'UserProfile|updateProfile|editUser') (After reviewing search results, assuming a relevant file like '/path/to/UserProfileService.java' was found) Okay, \`/path/to/UserProfileService.java\` seems like the most relevant file. I'll read its content to understand how updates are handled. -[tool_call: read_file for absolute_path '/path/to/UserProfileService.java'] +(I'll read the file: read_file on '/path/to/UserProfileService.java') (After reading the file) It appears the \`updateUserProfile\` method in \`UserProfileService.java\` is responsible for this. It expects a user ID and a \`UserProfileDTO\` object... @@ -1408,7 +1416,7 @@ It appears the \`updateUserProfile\` method in \`UserProfileService.java\` is re user: Where are all the 'app.config' files in this project? I need to check their settings. model: -[tool_call: glob for pattern '**/app.config'] +(I'll find all matching files: glob on '**/app.config') (Assuming GlobTool returns a list of paths like ['/path/to/moduleA/app.config', '/path/to/moduleB/app.config']) I found the following 'app.config' files: - /path/to/moduleA/app.config @@ -1483,6 +1491,7 @@ When requested to perform tasks like fixing bugs, adding features, refactoring, - **File Paths:** Always use absolute paths when referring to files with tools like 'read_file' or 'write_file'. Relative paths are not supported. You must provide an absolute path. - **Parallelism:** Execute multiple independent tool calls in parallel when feasible (i.e. searching the codebase). - **Command Execution:** Use the 'run_shell_command' tool for running shell commands, remembering the safety rule to explain modifying commands first. +- **Tool Calling (Critical):** Never emit pseudo tool-call markers (e.g. "tool_call: ...") in normal text. When you need to use a tool, call it using the tool-calling mechanism. - **Background Processes:** Use background processes (via \`&\`) for commands that are unlikely to stop on their own, e.g. \`node server.js &\`. If unsure, ask the user. - **Interactive Commands:** Try to avoid shell commands that are likely to require user interaction (e.g. \`git rebase -i\`). Use non-interactive versions of commands (e.g. \`npm init -y\` instead of \`npm init\`) when available, and otherwise remind the user that interactive shell commands are not supported and may cause hangs until canceled by the user. - **Remembering Facts:** Use the 'save_memory' tool to remember specific, *user-related* facts or preferences when the user explicitly asks, or when they state a clear, concise piece of information that would help personalize or streamline *your future interactions with them* (e.g., preferred coding style, common project paths they use, personal tool aliases). This tool is for user-specific information that should persist across sessions. Do *not* use it for general project context or information that belongs in project-specific \`GEMINI.md\` files. If unsure whether to save something, you can ask the user, "Should I remember that for you?" @@ -1512,24 +1521,24 @@ model: true user: list files here. -model: [tool_call: list_directory for path '.'] +model: I'll use the list_directory tool to list files in '.'. user: start the server implemented in server.js -model: [tool_call: run_shell_command for 'node server.js &' because it must run in the background] +model: I'll run \`node server.js &\` using the run_shell_command tool (it must run in the background). user: Refactor the auth logic in src/auth.py to use the requests library instead of urllib. model: Okay, I can refactor 'src/auth.py'. First, I'll analyze the code and check for a test safety net before planning any changes. -[tool_call: glob for path 'tests/test_auth.py'] -[tool_call: read_file for absolute_path '/path/to/tests/test_auth.py'] +(I'll search for tests: glob on 'tests/test_auth.py') +(I'll read the test file: read_file on '/path/to/tests/test_auth.py') (After analysis) Great, 'tests/test_auth.py' exists and covers the core authentication logic. With this safety net in place, I can safely plan the refactoring. I'll also confirm 'requests' is a dependency. -[tool_call: read_file for absolute_path '/path/to/requirements.txt'] +(I'll check dependencies: read_file on '/path/to/requirements.txt') (After analysis) Looks good, 'requests' is available. @@ -1542,9 +1551,9 @@ Here's the plan: Should I proceed? user: Yes model: -[tool_call: write_file or replace to apply the refactoring to 'src/auth.py'] +(I'll apply the refactor using write_file or replace on 'src/auth.py') Refactoring complete. Running verification... -[tool_call: run_shell_command for 'ruff check src/auth.py && pytest'] +(I'll run verification using run_shell_command: \`ruff check src/auth.py && pytest\`) (After verification passes) All checks passed. This is a stable checkpoint. @@ -1559,23 +1568,23 @@ model: I can run \`rm -rf ./temp\`. This will permanently delete the directory a user: Write tests for someFile.ts model: Okay, I can write those tests. First, I'll read \`someFile.ts\` to understand its functionality. -[tool_call: read_file for absolute_path '/path/to/someFile.ts' or use glob to find \`someFile.ts\` if its location is unknown] +(I'll read the file: read_file on '/path/to/someFile.ts', or use glob if its location is unknown) Now I'll look for existing or related test files to understand current testing conventions and dependencies. -[tool_call: read_many_files for paths ['**/*.test.ts', 'src/**/*.spec.ts'] assuming someFile.ts is in the src directory] +(I'll read related tests: read_many_files on ['**/*.test.ts', 'src/**/*.spec.ts']) (After reviewing existing tests and the file content) -[tool_call: write_file to create /path/to/someFile.test.ts with the test code] +(I'll write the new test file: write_file on '/path/to/someFile.test.ts') I've written the tests. Now I'll run the project's test command to verify them. -[tool_call: run_shell_command for 'npm run test'] +(I'll run tests using run_shell_command: \`npm run test\`) user: How do I update the user's profile information in this system? model: I'm not immediately sure how user profile information is updated. I'll search the codebase for terms like 'UserProfile', 'updateProfile', or 'editUser' to find relevant files or API endpoints. -[tool_call: search_file_content for pattern 'UserProfile|updateProfile|editUser'] +(I'll search the codebase: search_file_content on 'UserProfile|updateProfile|editUser') (After reviewing search results, assuming a relevant file like '/path/to/UserProfileService.java' was found) Okay, \`/path/to/UserProfileService.java\` seems like the most relevant file. I'll read its content to understand how updates are handled. -[tool_call: read_file for absolute_path '/path/to/UserProfileService.java'] +(I'll read the file: read_file on '/path/to/UserProfileService.java') (After reading the file) It appears the \`updateUserProfile\` method in \`UserProfileService.java\` is responsible for this. It expects a user ID and a \`UserProfileDTO\` object... @@ -1583,7 +1592,7 @@ It appears the \`updateUserProfile\` method in \`UserProfileService.java\` is re user: Where are all the 'app.config' files in this project? I need to check their settings. model: -[tool_call: glob for pattern '**/app.config'] +(I'll find all matching files: glob on '**/app.config') (Assuming GlobTool returns a list of paths like ['/path/to/moduleA/app.config', '/path/to/moduleB/app.config']) I found the following 'app.config' files: - /path/to/moduleA/app.config diff --git a/packages/core/src/core/prompts.ts b/packages/core/src/core/prompts.ts index 1f4403e6..43ebe4e8 100644 --- a/packages/core/src/core/prompts.ts +++ b/packages/core/src/core/prompts.ts @@ -100,6 +100,7 @@ When requested to perform tasks like fixing bugs, adding features, refactoring, - **File Paths:** Always use absolute paths when referring to files with tools like '${ReadFileTool.Name}' or '${WriteFileTool.Name}'. Relative paths are not supported. You must provide an absolute path. - **Parallelism:** Execute multiple independent tool calls in parallel when feasible (i.e. searching the codebase). - **Command Execution:** Use the '${ShellTool.Name}' tool for running shell commands, remembering the safety rule to explain modifying commands first. +- **Tool Calling (Critical):** Never emit pseudo tool-call markers (e.g. "tool_call: ...") in normal text. When you need to use a tool, call it using the tool-calling mechanism. - **Background Processes:** Use background processes (via \`&\`) for commands that are unlikely to stop on their own, e.g. \`node server.js &\`. If unsure, ask the user. - **Interactive Commands:** Try to avoid shell commands that are likely to require user interaction (e.g. \`git rebase -i\`). Use non-interactive versions of commands (e.g. \`npm init -y\` instead of \`npm init\`) when available, and otherwise remind the user that interactive shell commands are not supported and may cause hangs until canceled by the user. - **Remembering Facts:** Use the '${MemoryTool.Name}' tool to remember specific, *user-related* facts or preferences when the user explicitly asks, or when they state a clear, concise piece of information that would help personalize or streamline *your future interactions with them* (e.g., preferred coding style, common project paths they use, personal tool aliases). This tool is for user-specific information that should persist across sessions. Do *not* use it for general project context or information that belongs in project-specific \`GEMINI.md\` files. If unsure whether to save something, you can ask the user, "Should I remember that for you?" @@ -167,24 +168,24 @@ model: true user: list files here. -model: [tool_call: ${LSTool.Name} for path '.'] +model: I'll use the ${LSTool.Name} tool to list files in '.'. user: start the server implemented in server.js -model: [tool_call: ${ShellTool.Name} for 'node server.js &' because it must run in the background] +model: I'll run \`node server.js &\` using the ${ShellTool.Name} tool (it must run in the background). user: Refactor the auth logic in src/auth.py to use the requests library instead of urllib. model: Okay, I can refactor 'src/auth.py'. First, I'll analyze the code and check for a test safety net before planning any changes. -[tool_call: ${GlobTool.Name} for path 'tests/test_auth.py'] -[tool_call: ${ReadFileTool.Name} for absolute_path '/path/to/tests/test_auth.py'] +(I'll search for tests: ${GlobTool.Name} on 'tests/test_auth.py') +(I'll read the test file: ${ReadFileTool.Name} on '/path/to/tests/test_auth.py') (After analysis) Great, 'tests/test_auth.py' exists and covers the core authentication logic. With this safety net in place, I can safely plan the refactoring. I'll also confirm 'requests' is a dependency. -[tool_call: ${ReadFileTool.Name} for absolute_path '/path/to/requirements.txt'] +(I'll check dependencies: ${ReadFileTool.Name} on '/path/to/requirements.txt') (After analysis) Looks good, 'requests' is available. @@ -197,9 +198,9 @@ Here's the plan: Should I proceed? user: Yes model: -[tool_call: ${WriteFileTool.Name} or ${EditTool.Name} to apply the refactoring to 'src/auth.py'] +(I'll apply the refactor using ${WriteFileTool.Name} or ${EditTool.Name} on 'src/auth.py') Refactoring complete. Running verification... -[tool_call: ${ShellTool.Name} for 'ruff check src/auth.py && pytest'] +(I'll run verification using ${ShellTool.Name}: \`ruff check src/auth.py && pytest\`) (After verification passes) All checks passed. This is a stable checkpoint. ${(function () { @@ -219,23 +220,23 @@ model: I can run \`rm -rf ./temp\`. This will permanently delete the directory a user: Write tests for someFile.ts model: Okay, I can write those tests. First, I'll read \`someFile.ts\` to understand its functionality. -[tool_call: ${ReadFileTool.Name} for absolute_path '/path/to/someFile.ts' or use ${GlobTool.Name} to find \`someFile.ts\` if its location is unknown] +(I'll read the file: ${ReadFileTool.Name} on '/path/to/someFile.ts', or use ${GlobTool.Name} if its location is unknown) Now I'll look for existing or related test files to understand current testing conventions and dependencies. -[tool_call: ${ReadManyFilesTool.Name} for paths ['**/*.test.ts', 'src/**/*.spec.ts'] assuming someFile.ts is in the src directory] +(I'll read related tests: ${ReadManyFilesTool.Name} on ['**/*.test.ts', 'src/**/*.spec.ts']) (After reviewing existing tests and the file content) -[tool_call: ${WriteFileTool.Name} to create /path/to/someFile.test.ts with the test code] +(I'll write the new test file: ${WriteFileTool.Name} on '/path/to/someFile.test.ts') I've written the tests. Now I'll run the project's test command to verify them. -[tool_call: ${ShellTool.Name} for 'npm run test'] +(I'll run tests using ${ShellTool.Name}: \`npm run test\`) user: How do I update the user's profile information in this system? model: I'm not immediately sure how user profile information is updated. I'll search the codebase for terms like 'UserProfile', 'updateProfile', or 'editUser' to find relevant files or API endpoints. -[tool_call: ${GrepTool.Name} for pattern 'UserProfile|updateProfile|editUser'] +(I'll search the codebase: ${GrepTool.Name} on 'UserProfile|updateProfile|editUser') (After reviewing search results, assuming a relevant file like '/path/to/UserProfileService.java' was found) Okay, \`/path/to/UserProfileService.java\` seems like the most relevant file. I'll read its content to understand how updates are handled. -[tool_call: ${ReadFileTool.Name} for absolute_path '/path/to/UserProfileService.java'] +(I'll read the file: ${ReadFileTool.Name} on '/path/to/UserProfileService.java') (After reading the file) It appears the \`updateUserProfile\` method in \`UserProfileService.java\` is responsible for this. It expects a user ID and a \`UserProfileDTO\` object... @@ -243,7 +244,7 @@ It appears the \`updateUserProfile\` method in \`UserProfileService.java\` is re user: Where are all the 'app.config' files in this project? I need to check their settings. model: -[tool_call: ${GlobTool.Name} for pattern '**/app.config'] +(I'll find all matching files: ${GlobTool.Name} on '**/app.config') (Assuming GlobTool returns a list of paths like ['/path/to/moduleA/app.config', '/path/to/moduleB/app.config']) I found the following 'app.config' files: - /path/to/moduleA/app.config diff --git a/packages/core/src/custom_llm/converter.ts b/packages/core/src/custom_llm/converter.ts index a26ed104..419268f0 100644 --- a/packages/core/src/custom_llm/converter.ts +++ b/packages/core/src/custom_llm/converter.ts @@ -162,33 +162,104 @@ export class ModelConverter { const choice = response.choices[0]; const res = new GenerateContentResponse(); - if (choice.message.content) { + const message = (choice.message || {}) as any; + + if (Array.isArray(message.tool_calls) && message.tool_calls.length > 0) { res.candidates = [ { content: { - parts: [{ text: choice.message.content }], + parts: message.tool_calls.map((toolCall: any) => { + let args: Record = {}; + const rawArgs = toolCall?.function?.arguments; + if (typeof rawArgs === 'string' && rawArgs.trim().length > 0) { + try { + args = JSON.parse(rawArgs); + } catch { + args = {}; + } + } + const id = + typeof toolCall?.id === 'string' && toolCall.id.trim().length > 0 + ? toolCall.id + : `call_${Math.random().toString(36).slice(2)}`; + return { + functionCall: { + id, + name: toolCall.function.name, + args, + }, + }; + }), role: 'model', }, index: 0, safetyRatings: [], }, ]; - } else if (choice.message.tool_calls) { - res.candidates = [ - { - content: { - parts: choice.message.tool_calls.map((toolCall) => ({ - functionCall: { - name: toolCall.function.name, - args: JSON.parse(toolCall.function.arguments), - }, - })), - role: 'model', + } else { + const content = message.content; + const refusal = message.refusal; + const reasoningContent = message.reasoning_content; + + let text: string | undefined; + if (typeof content === 'string' && content.trim().length > 0) { + text = content; + } else if (Array.isArray(content)) { + const segments = content + .map((part: any) => { + if (typeof part === 'string') { + return part; + } + if (typeof part === 'object' && part !== null && 'text' in part) { + return typeof part.text === 'string' ? part.text : ''; + } + return ''; + }) + .filter(Boolean); + if (segments.length > 0) { + text = segments.join(''); + } + } else if (typeof content === 'object' && content !== null) { + if ( + 'text' in content && + typeof content.text === 'string' && + content.text.trim().length > 0 + ) { + text = content.text; + } else { + try { + text = JSON.stringify(content); + } catch { + text = String(content); + } + } + } + + if (typeof text !== 'string' || text.trim().length === 0) { + if (typeof refusal === 'string' && refusal.trim().length > 0) { + text = refusal; + } else if ( + typeof reasoningContent === 'string' && + reasoningContent.trim().length > 0 + ) { + text = reasoningContent; + } else if (typeof content === 'string') { + text = content; + } + } + + if (typeof text === 'string') { + res.candidates = [ + { + content: { + parts: [{ text }], + role: 'model', + }, + index: 0, + safetyRatings: [], }, - index: 0, - safetyRatings: [], - }, - ]; + ]; + } } res.usageMetadata = { promptTokenCount: response.usage?.prompt_tokens || 0, @@ -228,13 +299,24 @@ export class ModelConverter { { content: { parts: Array.from(toolCallMap.entries()).map( - ([_index, toolCall]) => ({ - functionCall: { - id: `call_${Math.random().toString(36).slice(2)}`, - name: toolCall.name, - args: toolCall.arguments ? JSON.parse(toolCall.arguments) : {}, - }, - }), + ([_index, toolCall]) => { + let args: Record = {}; + if (toolCall.arguments && toolCall.arguments.trim().length > 0) { + try { + args = JSON.parse(toolCall.arguments); + } catch { + args = {}; + } + } + return { + functionCall: { + id: + toolCall.id || `call_${Math.random().toString(36).slice(2)}`, + name: toolCall.name, + args, + }, + }; + }, ), role: 'model', }, @@ -297,10 +379,15 @@ export class ModelConverter { ): void { const idx = toolCall.index; const current = toolCallMap.get(idx) || { + id: '', name: '', arguments: '', }; + if (toolCall.id) { + current.id = toolCall.id; + } + if (toolCall.function?.name) { current.name = toolCall.function.name; } @@ -319,14 +406,8 @@ export class ModelConverter { chunk: OpenAI.Chat.Completions.ChatCompletionChunk, toolCallMap: ToolCallMap, ): { response: GenerateContentResponse | null; shouldReturn: boolean } { - if (chunk.usage && chunk.usage.total_tokens) { - return { - response: this.toGeminiStreamUsageResponse(chunk.usage), - shouldReturn: true, - }; - } - - const choice = chunk.choices[0]; + const usage = chunk.usage; + const choice = chunk.choices?.[0]; if (choice?.delta?.content) { return { @@ -341,9 +422,16 @@ export class ModelConverter { } } - if (choice.finish_reason === 'tool_calls' && toolCallMap.size > 0) { + if (choice?.finish_reason === 'tool_calls' && toolCallMap.size > 0) { const response = this.toGeminiStreamToolCallsResponse(toolCallMap); toolCallMap.clear(); + if (usage?.total_tokens) { + response.usageMetadata = { + promptTokenCount: usage.prompt_tokens || 0, + candidatesTokenCount: usage.completion_tokens || 0, + totalTokenCount: usage.total_tokens || 0, + }; + } return { response, shouldReturn: false, @@ -351,8 +439,20 @@ export class ModelConverter { } if (choice?.finish_reason) { + const response = this.toGeminiStreamEndResponse(); + if (usage?.total_tokens) { + response.usageMetadata = { + promptTokenCount: usage.prompt_tokens || 0, + candidatesTokenCount: usage.completion_tokens || 0, + totalTokenCount: usage.total_tokens || 0, + }; + } + return { response, shouldReturn: true }; + } + + if (usage?.total_tokens) { return { - response: this.toGeminiStreamEndResponse(), + response: this.toGeminiStreamUsageResponse(usage), shouldReturn: true, }; } diff --git a/packages/core/src/custom_llm/index.ts b/packages/core/src/custom_llm/index.ts index f36a5186..8425dd86 100644 --- a/packages/core/src/custom_llm/index.ts +++ b/packages/core/src/custom_llm/index.ts @@ -56,6 +56,12 @@ export class CustomLLMContentGenerator implements ContentGenerator { ): Promise> { const messages = ModelConverter.toOpenAIMessages(request); const tools = extractToolFunctions(request.config) || []; + if (process.env.EASY_LLM_CLI_DEBUG_TOOL_CALLS) { + console.error( + '[debug] openai tools:', + JSON.stringify(tools.map((t) => t.function?.name)), + ); + } const stream = await this.model.chat.completions.create({ messages, stream: true, @@ -66,6 +72,31 @@ export class CustomLLMContentGenerator implements ContentGenerator { const map: ToolCallMap = new Map(); return (async function* (): AsyncGenerator { for await (const chunk of stream) { + if (process.env.EASY_LLM_CLI_DEBUG_TOOL_CALLS) { + const choice = chunk?.choices?.[0]; + const delta = choice?.delta as any; + if (delta?.tool_calls) { + console.error( + '[debug] stream tool_calls:', + JSON.stringify(delta.tool_calls), + ); + } + if (delta?.content) { + console.error('[debug] stream content:', JSON.stringify(delta.content)); + } + if (delta?.reasoning_content) { + console.error( + '[debug] stream reasoning_content:', + JSON.stringify(delta.reasoning_content), + ); + } + if (choice?.finish_reason) { + console.error( + '[debug] stream finish_reason:', + JSON.stringify(choice.finish_reason), + ); + } + } const { response } = ModelConverter.processStreamChunk(chunk, map); if (response) { yield response; @@ -87,9 +118,11 @@ export class CustomLLMContentGenerator implements ContentGenerator { request: GenerateContentParameters, ): Promise { const messages = ModelConverter.toOpenAIMessages(request); + const wantsJson = request.config?.responseMimeType === 'application/json'; const completion = await this.model.chat.completions.create({ messages, stream: false, + ...(wantsJson ? { response_format: { type: 'json_object' } } : {}), ...this.config, }); diff --git a/packages/core/src/custom_llm/types.ts b/packages/core/src/custom_llm/types.ts index e644c348..a7c128a7 100644 --- a/packages/core/src/custom_llm/types.ts +++ b/packages/core/src/custom_llm/types.ts @@ -21,6 +21,7 @@ export interface CustomLLMContentGeneratorConfig { * Tool call data structure for streaming */ export interface ToolCallData { + id: string; name: string; arguments: string; } diff --git a/packages/core/src/utils/nextSpeakerChecker.test.ts b/packages/core/src/utils/nextSpeakerChecker.test.ts index 475b5662..6f4509b5 100644 --- a/packages/core/src/utils/nextSpeakerChecker.test.ts +++ b/packages/core/src/utils/nextSpeakerChecker.test.ts @@ -47,6 +47,7 @@ describe('checkNextSpeaker', () => { const abortSignal = new AbortController().signal; beforeEach(() => { + vi.stubEnv('USE_CUSTOM_LLM', 'false'); MockConfig = vi.mocked(Config); const mockConfigInstance = new MockConfig( 'test-api-key', @@ -81,6 +82,7 @@ describe('checkNextSpeaker', () => { afterEach(() => { vi.clearAllMocks(); + vi.unstubAllEnvs(); }); it('should return null if history is empty', async () => { @@ -107,6 +109,22 @@ describe('checkNextSpeaker', () => { expect(mockGeminiClient.generateJson).not.toHaveBeenCalled(); }); + it('should not call generateJson when using a custom LLM', async () => { + vi.stubEnv('USE_CUSTOM_LLM', '1'); + (chatInstance.getHistory as Mock).mockReturnValue([ + { role: 'model', parts: [{ text: 'Let me check Podfile:' }] }, + ] as Content[]); + + const result = await checkNextSpeaker( + chatInstance, + mockGeminiClient, + abortSignal, + ); + + expect(result?.next_speaker).toBe('model'); + expect(mockGeminiClient.generateJson).not.toHaveBeenCalled(); + }); + it("should return { next_speaker: 'model' } when model intends to continue", async () => { (chatInstance.getHistory as Mock).mockReturnValue([ { role: 'model', parts: [{ text: 'I will now do something.' }] }, diff --git a/packages/core/src/utils/nextSpeakerChecker.ts b/packages/core/src/utils/nextSpeakerChecker.ts index 165f277a..6ae7d195 100644 --- a/packages/core/src/utils/nextSpeakerChecker.ts +++ b/packages/core/src/utils/nextSpeakerChecker.ts @@ -7,6 +7,7 @@ import { Content, SchemaUnion, Type } from '@google/genai'; import { GeminiClient } from '../core/client.js'; import { GeminiChat } from '../core/geminiChat.js'; +import { getResponseTextFromParts } from './generateContentResponseUtilities.js'; import { isFunctionResponse } from './messageInspectors.js'; const CHECK_PROMPT = `Analyze *only* the content and structure of your immediately preceding response (your last turn in the conversation history). Based *strictly* on that response, determine who should logically speak next: the 'user' or the 'model' (you). @@ -121,10 +122,51 @@ export async function checkNextSpeaker( return null; } - const contents: Content[] = [ - ...curatedHistory, - { role: 'user', parts: [{ text: CHECK_PROMPT }] }, - ]; + const useCustomLLM = + process.env.USE_CUSTOM_LLM && process.env.USE_CUSTOM_LLM !== 'false'; + + if (useCustomLLM) { + const lastText = getResponseTextFromParts(lastMessage.parts ?? []) ?? ''; + const trimmed = lastText.trim(); + + if (!trimmed) { + return { + reasoning: + 'The last model message contained no text, so the model should speak next.', + next_speaker: 'model', + }; + } + + if (/[??]\s*$/.test(trimmed)) { + return { + reasoning: + 'The last model response ends with a question, so the user should speak next.', + next_speaker: 'user', + }; + } + + const looksIncomplete = /[::…]\s*$/.test(trimmed) || /\.\.\.\s*$/.test(trimmed); + const indicatesImmediateNextAction = + /(^|\n)\s*(next|now|let me|i(?:'| a)m going to|i will|starting|moving on|proceeding)\b/i.test( + trimmed, + ) || /(让我|我先|我将|我会|接下来|下面|开始|继续)/.test(trimmed); + + if (looksIncomplete || indicatesImmediateNextAction) { + return { + reasoning: + 'The last model response indicates an immediate next action or looks incomplete, so the model should speak next.', + next_speaker: 'model', + }; + } + + return { + reasoning: + 'The last model response appears complete and does not ask a question, so the user should speak next.', + next_speaker: 'user', + }; + } + + const contents: Content[] = [lastMessage, { role: 'user', parts: [{ text: CHECK_PROMPT }] }]; try { const parsedResponse = (await geminiClient.generateJson(