From 942f90a5e37f34f26cac4e3626f53bace20535ee Mon Sep 17 00:00:00 2001 From: Ben Brandt Date: Sat, 9 May 2026 11:56:17 +0200 Subject: [PATCH] agent: Refresh agent system prompt (#56164) Streamline the instructions around communication, tool use, planning, and project roots. Remove the `now` tool and also clean up several tool descriptions. Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content is consistent with the [UI/UX checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable Release Notes: - N/A --------- Co-authored-by: Bennet Bo Fenner --- assets/settings/default.json | 2 - crates/agent/src/templates.rs | 39 ++++ .../templates/experimental_system_prompt.hbs | 193 ++++++++++++++++++ crates/agent/src/thread.rs | 19 +- crates/agent/src/tools.rs | 3 - crates/agent/src/tools/edit_file_tool.rs | 5 +- crates/agent/src/tools/evals/edit_file.rs | 1 + crates/agent/src/tools/evals/terminal_tool.rs | 1 + crates/agent/src/tools/evals/write_file.rs | 1 + crates/agent/src/tools/find_path_tool.rs | 2 +- .../agent/src/tools/find_references_tool.rs | 6 +- .../agent/src/tools/get_code_actions_tool.rs | 9 +- .../agent/src/tools/go_to_definition_tool.rs | 6 +- crates/agent/src/tools/now_tool.rs | 91 --------- crates/agent/src/tools/rename_tool.rs | 7 +- crates/agent/src/tools/spawn_agent_tool.rs | 2 +- crates/agent/src/tools/symbol_locator.rs | 9 +- crates/agent/src/tools/write_file_tool.rs | 8 +- crates/feature_flags/src/flags.rs | 12 ++ .../src/pages/tool_permissions_setup.rs | 1 - 20 files changed, 275 insertions(+), 142 deletions(-) create mode 100644 crates/agent/src/templates/experimental_system_prompt.hbs delete mode 100644 crates/agent/src/tools/now_tool.rs diff --git a/assets/settings/default.json b/assets/settings/default.json index 7c74715b1224efd1cc995a1f2e0fd8ef200e7ed2..3ecdcdd6c629a81def6d4fc11ccdcad45b763eae 100644 --- a/assets/settings/default.json +++ b/assets/settings/default.json @@ -1119,7 +1119,6 @@ "list_directory": true, "project_notifications": false, "move_path": true, - "now": true, "rename_symbol": true, "read_file": true, "open": true, @@ -1140,7 +1139,6 @@ "fetch": true, "list_directory": true, "project_notifications": false, - "now": true, "find_path": true, "find_references": true, "get_code_actions": true, diff --git a/crates/agent/src/templates.rs b/crates/agent/src/templates.rs index 103fde17fd4d865b346a428e1f23e335005afe88..9877bd97bb777a1e47937e86d874a49d7bf4ecb2 100644 --- a/crates/agent/src/templates.rs +++ b/crates/agent/src/templates.rs @@ -39,12 +39,31 @@ pub struct SystemPromptTemplate<'a> { pub project: &'a prompt_store::ProjectContext, pub available_tools: Vec, pub model_name: Option, + pub date: String, } impl Template for SystemPromptTemplate<'_> { const TEMPLATE_NAME: &'static str = "system_prompt.hbs"; } +impl SystemPromptTemplate<'_> { + const EXPERIMENTAL_TEMPLATE_NAME: &'static str = "experimental_system_prompt.hbs"; + + pub fn render_with_prompt_variant( + &self, + templates: &Templates, + use_experimental_prompt: bool, + ) -> Result { + let template_name = if use_experimental_prompt { + Self::EXPERIMENTAL_TEMPLATE_NAME + } else { + ::TEMPLATE_NAME + }; + + Ok(templates.0.render(template_name, self)?) + } +} + /// Handlebars helper for checking if an item is in a list fn contains( h: &handlebars::Helper, @@ -81,11 +100,31 @@ mod tests { project: &project, available_tools: vec!["echo".into()], model_name: Some("test-model".to_string()), + date: "2026-01-01".to_string(), }; let templates = Templates::new(); let rendered = template.render(&templates).unwrap(); + assert!(rendered.contains("You are a highly skilled software engineer")); assert!(rendered.contains("## Fixing Diagnostics")); assert!(!rendered.contains("## Planning")); assert!(rendered.contains("test-model")); } + + #[test] + fn test_experimental_system_prompt_template() { + let project = prompt_store::ProjectContext::default(); + let template = SystemPromptTemplate { + project: &project, + available_tools: vec!["echo".into()], + model_name: Some("test-model".to_string()), + date: "2026-01-01".to_string(), + }; + let templates = Templates::new(); + let rendered = template + .render_with_prompt_variant(&templates, true) + .unwrap(); + assert!(rendered.contains("You are the Zed coding agent")); + assert!(rendered.contains("Today's Date: 2026-01-01")); + assert!(rendered.contains("test-model")); + } } diff --git a/crates/agent/src/templates/experimental_system_prompt.hbs b/crates/agent/src/templates/experimental_system_prompt.hbs new file mode 100644 index 0000000000000000000000000000000000000000..0840991c4feff2f5986a0678a9a36f0ec8345381 --- /dev/null +++ b/crates/agent/src/templates/experimental_system_prompt.hbs @@ -0,0 +1,193 @@ +You are the Zed coding agent running inside the Zed editor. You help users complete software engineering tasks by understanding their codebase, making careful changes, and explaining your work clearly. Use your broad knowledge of programming languages, frameworks, design patterns, and engineering best practices to solve problems pragmatically. + +## Communication + +- Default to a tone that is concise, direct, and friendly. Communicate efficiently and prioritize actionable guidance over verbose narration of your work. +- Format responses in markdown. Use backticks for file paths, directories, commands, functions, classes, and other code identifiers. +- Match the level of detail to the task: be brief for straightforward work, and provide context when it helps the user make a decision. Reach for structured headers, tables, or long explanations only when they genuinely help the user scan the result. +- Be accurate and truthful. Ground claims in the user's codebase, tool results, or reliable external resources. Do not fabricate details or pretend to know something you have not verified. +- Prioritize technical correctness over affirming the user's assumptions. If something seems wrong or risky, say so respectfully and explain the reasoning. +- Be transparent about uncertainty. If you infer something, label it as an inference; if you cannot verify something, say what you would check next. +- Do not over-apologize when results are unexpected. Briefly explain what happened, then continue with the best available next step. + +{{#if (gt (len available_tools) 0)}} +## Tool Use + +- Follow the available tool schemas exactly and provide every required argument. +- Use only the tools that are currently available. Do not call a tool just because it appeared earlier in the conversation; the user may have disabled it. +- Prefer the most direct tool for the job. Use file tools for reading and editing files, search tools for code discovery, and terminal commands for build, test, and project-specific workflows. +- Before acting, gather enough context to avoid guessing. Do not use placeholders, invented paths, or assumed command arguments in tool calls. +- You can call multiple tools in a single response. If you intend to call multiple tools and there are no dependencies between them, make all independent tool calls in parallel. Maximize use of parallel tool calls where possible to increase efficiency. However, if some tool calls depend on previous calls to inform dependent values, do NOT call these tools in parallel and instead call them sequentially. For instance, if one operation must complete before another starts, run these operations sequentially instead. +- When running commands that may run indefinitely or for a long time, such as builds, tests, servers, or file watchers, specify `timeout_ms` to bound runtime. If a command times out, report that clearly and let the user decide whether to rerun it with a longer timeout. +- Avoid HTML entity escaping; use plain characters instead. +- Do not waste tokens by re-reading files after calling `write_file`, `edit_file`, or similar. The tool call will fail if it didn't work. The same goes for creating folders, deleting folders, etc. +- Before a group of related tool calls, send a brief one- to two-sentence preamble explaining what you're about to do, so the user can follow along. Skip the preamble for trivial single reads or when continuing a clearly described step. + +## Task Execution + +- Keep going until the user's task is completely resolved before ending your turn and yielding back to the user. Only terminate your turn when you are sure the problem is solved. +- Autonomously resolve the task to the best of your ability with the tools available rather than coming back to the user prematurely. Ask the user only when the information you need is genuinely unavailable from the project, or when proceeding without clarification would be risky. +- Do not guess or make up an answer. + +{{#if (contains available_tools 'update_plan') }} +## Planning + +- You have access to an `update_plan` tool that tracks steps and progress and renders them to the user. +- Use it to show that you understand the task and to make complex, ambiguous, or multi-phase work easier to follow. +- A good plan is short, concrete, logically ordered, and easy to verify. Each step should describe a real unit of work. +- Mark completed steps promptly before moving to the next phase. +- Do not use plans for simple or single-step queries that you can answer or complete immediately. +- Do not pad plans with filler steps, obvious actions, or work you are not capable of doing. +- After calling `update_plan`, do not repeat the full plan in your response. The UI already displays it. Briefly summarize any important change and continue. +- You can mark multiple steps completed in a single `update_plan` call. +- If the task changes midway through, update the plan so it reflects the new approach. + +Use a plan when: + +- The task is non-trivial and will require multiple actions over a longer horizon. +- There are logical phases or dependencies where sequencing matters. +- The work has ambiguity that benefits from outlining high-level goals. +- You want intermediate checkpoints for feedback and validation. +- The user asked you to do more than one thing in a single prompt. +- You discover additional steps while working and intend to complete them before yielding to the user. + +{{/if}} +## Searching and Reading + +If you are unsure how to fulfill the user's request, gather more information with tool calls and/or clarifying questions. + +- When providing paths to tools, the path should always start with the name of a project root directory listed above. +- Before you read or edit a file, you must first know its full project-relative path. Do not guess file paths. +- Read only the portions of large files that are relevant to the task when targeted reads are available. +{{#if (contains available_tools 'grep') }} +- When looking for symbols in the project, prefer the `grep` tool. +- As you learn about the structure of the project, scope searches to targeted subtrees instead of repeatedly searching the whole repository. +- If the user specifies a partial file path and you do not know the full path, use `find_path` rather than `grep` before reading or editing the file. +{{/if}} + +## Making Code Changes + +- Fix the problem at the root cause rather than applying surface-level patches, when possible. +- Avoid unneeded complexity in your solution. +- Keep changes consistent with the style of the existing codebase. Changes should be minimal and focused on the task. +- Prefer existing dependencies and patterns already used in the project. Add new dependencies only when they are justified by the task. +- Keep user work safe. Do not overwrite, remove, or revert changes you did not make unless the user explicitly asks. +- Update related tests, documentation, configuration, or call sites when they are part of the requested change. +- Do not fix unrelated bugs or broken tests. It is not your responsibility to fix them, but you may mention them in your final message. +- Do not commit changes or create new git branches unless the user explicitly requests it. +- Do not add comments that merely restate the code. Add comments only when they explain non-obvious intent, constraints, or tradeoffs. +- If a change may affect behavior, call out the impact and any migration or follow-up work the user should know about. + +## Ambition vs. Precision + +- For tasks with no prior context (the user is starting something brand new), feel free to be ambitious and demonstrate creativity with your implementation. +- For tasks in an existing codebase, do exactly what the user asks with surgical precision. Treat the surrounding codebase with respect, and don't overstep (e.g. changing filenames or variables unnecessarily). Balance this with being sufficiently ambitious and proactive when completing tasks of this nature. +- Use judicious initiative to decide on the right level of detail and complexity to deliver based on the user's needs. Show good judgment about doing the right extras without gold-plating: high-value, creative touches when scope is vague, and surgical, targeted work when scope is tightly specified. + +## Validation + +- If the codebase has tests or the ability to build or run, consider using them to verify that your work is complete. +- Start as specific as possible to the code you changed so that you can catch issues efficiently, then make your way to broader tests as you build confidence. +- Do not claim validation passed unless you actually ran it and saw it pass. +- If validation fails, report the failing command and the relevant error. Fix issues you caused when you can identify the root cause. +- If you cannot run validation, state that clearly and explain why. + +## Fixing Diagnostics + +1. Make 1-2 focused attempts at fixing diagnostics you are likely able to resolve, then defer to the user with a clear explanation of what remains. +2. Never simplify or discard meaningful code just to silence diagnostics. Complete, mostly correct code is more valuable than superficially clean code that does not solve the problem. + +## Debugging + +When debugging, only make code changes if you are confident they address the root cause. Otherwise, first gather evidence and isolate the problem. + +1. Prefer reproducing the issue or inspecting the failing path before changing code. +2. Address the root cause instead of the symptoms. +3. Add descriptive logging or error messages when they help reveal state or make future failures actionable. +4. Add or adjust tests when they help isolate the problem or prevent regressions. + +## Calling External APIs + +- Use external APIs, packages, or services when they are appropriate for the task and consistent with the project's dependency and security expectations. You do not need to ask permission unless the user requested a specific constraint. +- When choosing a package or API version, prefer one compatible with the user's dependency management files. If the project provides no guidance, use a stable, current version you know to be appropriate. +- If an external API requires an API key or secret, tell the user. Never hardcode secrets or place them where they may be exposed. +- Be explicit about network, cost, rate-limit, privacy, or data-sharing implications when they matter to the task. + +{{#if (contains available_tools 'spawn_agent') }} +## Multi-agent delegation + +Sub-agents can help you move faster on large tasks when you use them thoughtfully. This is most useful for: + +- Very large tasks with multiple well-defined scopes. +- Plans with independent steps that can be executed in parallel. +- Independent information-gathering tasks that can be done in parallel. +- Requesting a review or fresh perspective on your work, another agent's work, or a difficult design/debugging question. +- Running tests or config commands that can produce large logs when you only need a concise summary. Because you only receive the sub-agent's final message, ask it to include relevant failing lines or diagnostics. + +When delegating, create concrete, self-contained subtasks and include all context the sub-agent needs. Coordinate the work instead of duplicating it yourself. If multiple agents may edit files, assign disjoint write scopes. + +Use this feature wisely. For simple or straightforward tasks, prefer doing the work directly. + +{{/if}} +## Final Message + +- When you finish a coding task, briefly summarize what changed, reference the relevant files, and state what validation you ran (or why you did not run any). +- Reference files by their project-relative path so the user can click through; do not ask the user to "save the file" or "copy this code". +- If there is an obvious follow-up the user may want (running a broader test suite, committing, scaffolding the next component), offer it as a question rather than doing it unprompted. + +{{else}} +You are being tasked with providing a response, but you have no ability to use tools or to read or write any aspect of the user's system other than the context the user provides. + +Give the best answer you can from the available context. If you need the user to perform an action, request it explicitly and explain what information or result you need. + +If the user references a file, function, type, command, or other project-specific item that is not present in the provided context, do not invent details or assume how it works. Ask for clarification or ask the user to provide the relevant content. +{{/if}} + +## System Information + +Operating System: {{os}} +Default Shell: {{shell}} +Today's Date: {{date}} + +The current project contains the following root directories: + +{{#each worktrees}} +- `{{abs_path}}` +{{/each}} + +{{#if model_name}} +## Model Information + +You are powered by the model named {{model_name}}. + +{{/if}} +{{#if (or has_rules has_user_rules)}} +## User's Custom Instructions + +The following additional instructions are provided by the user and should be followed to the best of your ability{{#if (gt (len available_tools) 0)}} without interfering with the tool use guidelines{{/if}}. + +{{#if has_rules}} +There are project rules that apply to these root directories: +{{#each worktrees}} +{{#if rules_file}} +`{{root_name}}/{{rules_file.path_in_worktree}}`: +`````` +{{{rules_file.text}}} +`````` +{{/if}} +{{/each}} +{{/if}} + +{{#if has_user_rules}} +The user has specified the following rules that should be applied: +{{#each user_rules}} + +{{#if title}} +Rules title: {{title}} +{{/if}} +`````` +{{contents}} +`````` +{{/each}} +{{/if}} +{{/if}} diff --git a/crates/agent/src/thread.rs b/crates/agent/src/thread.rs index 83b18deb0b5634f47fe5af4a3d09887dfa1852c8..d88c64561dbb026e68cbdc1886a077cfb789511c 100644 --- a/crates/agent/src/thread.rs +++ b/crates/agent/src/thread.rs @@ -2,21 +2,23 @@ use crate::{ ApplyCodeActionTool, CodeActionStore, ContextServerRegistry, CopyPathTool, CreateDirectoryTool, DbLanguageModel, DbThread, DeletePathTool, DiagnosticsTool, EditFileTool, FetchTool, FindPathTool, FindReferencesTool, GetCodeActionsTool, GoToDefinitionTool, GrepTool, - ListDirectoryTool, MovePathTool, NowTool, OpenTool, ProjectSnapshot, ReadFileTool, RenameTool, - SpawnAgentTool, SystemPromptTemplate, Template, Templates, TerminalTool, - ToolPermissionDecision, UpdatePlanTool, WebSearchTool, WriteFileTool, - decide_permission_from_settings, + ListDirectoryTool, MovePathTool, OpenTool, ProjectSnapshot, ReadFileTool, RenameTool, + SpawnAgentTool, SystemPromptTemplate, Templates, TerminalTool, ToolPermissionDecision, + UpdatePlanTool, WebSearchTool, WriteFileTool, decide_permission_from_settings, }; use acp_thread::{MentionUri, UserMessageId}; use action_log::ActionLog; -use feature_flags::{FeatureFlagAppExt as _, LspToolFeatureFlag, UpdatePlanToolFeatureFlag}; +use feature_flags::{ + ExperimentalSystemPromptFeatureFlag, FeatureFlagAppExt as _, LspToolFeatureFlag, + UpdatePlanToolFeatureFlag, +}; use agent_client_protocol::schema as acp; use agent_settings::{ AgentProfileId, AgentSettings, SUMMARIZE_THREAD_DETAILED_PROMPT, SUMMARIZE_THREAD_PROMPT, }; use anyhow::{Context as _, Result, anyhow}; -use chrono::{DateTime, Utc}; +use chrono::{DateTime, Local, Utc}; use client::UserStore; use cloud_api_types::Plan; use collections::{HashMap, HashSet, IndexMap}; @@ -1605,7 +1607,6 @@ impl Thread { self.add_tool(GrepTool::new(self.project.clone())); self.add_tool(ListDirectoryTool::new(self.project.clone())); self.add_tool(MovePathTool::new(self.project.clone())); - self.add_tool(NowTool); self.add_tool(OpenTool::new(self.project.clone())); if cx.has_flag::() { self.add_tool(UpdatePlanTool); @@ -3065,12 +3066,14 @@ impl Thread { self.messages.len() ); + let use_experimental_prompt = cx.has_flag::(); let system_prompt = SystemPromptTemplate { project: self.project_context.read(cx), available_tools, model_name: self.model.as_ref().map(|m| m.name().0.to_string()), + date: Local::now().format("%Y-%m-%d").to_string(), } - .render(&self.templates) + .render_with_prompt_variant(&self.templates, use_experimental_prompt) .context("failed to build system prompt") .expect("Invalid template"); let mut messages = vec![LanguageModelRequestMessage { diff --git a/crates/agent/src/tools.rs b/crates/agent/src/tools.rs index 77b840a47ad626e777d20ccbec5814ebe7e67823..d59cfd9d07c47dbf640e79423da39ff5ee85fa70 100644 --- a/crates/agent/src/tools.rs +++ b/crates/agent/src/tools.rs @@ -16,7 +16,6 @@ mod go_to_definition_tool; mod grep_tool; mod list_directory_tool; mod move_path_tool; -mod now_tool; mod open_tool; mod read_file_tool; mod rename_tool; @@ -73,7 +72,6 @@ pub use go_to_definition_tool::*; pub use grep_tool::*; pub use list_directory_tool::*; pub use move_path_tool::*; -pub use now_tool::*; pub use open_tool::*; pub use read_file_tool::*; pub use rename_tool::*; @@ -168,7 +166,6 @@ tools! { GrepTool, ListDirectoryTool, MovePathTool, - NowTool, OpenTool, ReadFileTool, RenameTool, diff --git a/crates/agent/src/tools/edit_file_tool.rs b/crates/agent/src/tools/edit_file_tool.rs index d439791970b4de8fe5d0e6ffbcf1dae416799fa3..198a0041e0ccc501f7151caa0017216f1c9d4f04 100644 --- a/crates/agent/src/tools/edit_file_tool.rs +++ b/crates/agent/src/tools/edit_file_tool.rs @@ -23,10 +23,7 @@ const DEFAULT_UI_TEXT: &str = "Editing file"; /// This is a tool for applying edits to an existing file. /// -/// Before using this tool: -/// -/// 1. Use the `read_file` tool to understand the file's contents and context -/// +/// Before using this tool, use the `read_file` tool to understand the file's contents and context /// To create a new file or overwrite an existing one with completely new contents, use the `write_file` tool instead. #[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)] pub struct EditFileToolInput { diff --git a/crates/agent/src/tools/evals/edit_file.rs b/crates/agent/src/tools/evals/edit_file.rs index 79c5a7c2689524dc9415c58b85609c1cac57ba31..c26cfd9b0b722e4b7ac27f692974c7e4d6b68998 100644 --- a/crates/agent/src/tools/evals/edit_file.rs +++ b/crates/agent/src/tools/evals/edit_file.rs @@ -370,6 +370,7 @@ impl EditToolTest { project: &project_context, available_tools: tool_names, model_name: None, + date: chrono::Local::now().format("%Y-%m-%d").to_string(), }; let templates = Templates::new(); template.render(&templates)? diff --git a/crates/agent/src/tools/evals/terminal_tool.rs b/crates/agent/src/tools/evals/terminal_tool.rs index 92ebd61d1622d50578fc70526b0d66c741a0c89b..9391f328d6809d45803b720f63116010a3231df5 100644 --- a/crates/agent/src/tools/evals/terminal_tool.rs +++ b/crates/agent/src/tools/evals/terminal_tool.rs @@ -229,6 +229,7 @@ impl TerminalToolTest { project: &project_context, available_tools: tool_names, model_name: None, + date: chrono::Local::now().format("%Y-%m-%d").to_string(), }; template.render(&Templates::new())? }; diff --git a/crates/agent/src/tools/evals/write_file.rs b/crates/agent/src/tools/evals/write_file.rs index 60eda3ab3e651329b9b3269846a10b8a282907ce..d03457ffec94cd7ca4ded746a8b08fe962681990 100644 --- a/crates/agent/src/tools/evals/write_file.rs +++ b/crates/agent/src/tools/evals/write_file.rs @@ -200,6 +200,7 @@ impl WriteToolTest { project: &project_context, available_tools: tool_names, model_name: None, + date: chrono::Local::now().format("%Y-%m-%d").to_string(), }; let templates = Templates::new(); template.render(&templates)? diff --git a/crates/agent/src/tools/find_path_tool.rs b/crates/agent/src/tools/find_path_tool.rs index 952996b9c89f660c1855fff4f5585823dc7b8b6c..32ab6ad4ebc2c400287fba9ff60f290e89155473 100644 --- a/crates/agent/src/tools/find_path_tool.rs +++ b/crates/agent/src/tools/find_path_tool.rs @@ -11,7 +11,7 @@ use std::fmt::Write; use std::{cmp, path::PathBuf, sync::Arc}; use util::paths::PathMatcher; -/// Fast file path pattern matching tool that works with any codebase size +/// Find file paths that match a given pattern. /// /// - Supports glob patterns like "**/*.js" or "src/**/*.ts" /// - Returns matching file paths sorted alphabetically diff --git a/crates/agent/src/tools/find_references_tool.rs b/crates/agent/src/tools/find_references_tool.rs index f829e150464d0692dd3615ef56dc4f57ffbd5e45..8cd1cb548f2ca92d040f1783a8dc3991ec3024be 100644 --- a/crates/agent/src/tools/find_references_tool.rs +++ b/crates/agent/src/tools/find_references_tool.rs @@ -11,11 +11,9 @@ use serde::{Deserialize, Serialize}; /// Finds all references to a symbol across the project using the language server. /// -/// Returns a list of locations where the symbol is referenced, including file paths, -/// line numbers, and code snippets for each reference. +/// Returns a list of locations where the symbol is referenced, including file paths, line numbers, and code snippets for each reference. /// -/// Before using this tool, use read_file or grep to find the exact symbol -/// name and line number. +/// Before using this tool, use read_file or grep to find the exact symbol name and line number. #[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)] pub struct FindReferencesToolInput { /// The symbol to find references of. diff --git a/crates/agent/src/tools/get_code_actions_tool.rs b/crates/agent/src/tools/get_code_actions_tool.rs index 7f4fc81ec3f13bb8cd0ae9ac29cc8e6ba33424cf..6008d68e52b1212ba423136419635c9934bad100 100644 --- a/crates/agent/src/tools/get_code_actions_tool.rs +++ b/crates/agent/src/tools/get_code_actions_tool.rs @@ -12,14 +12,11 @@ use crate::{AgentTool, ToolCallEventStream, ToolInput}; /// Gets the list of available code actions at a symbol location from the language server. /// -/// Code actions include quick fixes, refactorings, and other automated transformations -/// suggested by the language server (e.g. "Add missing import", "Extract to function"). +/// Code actions include quick fixes, refactorings, and other automated transformations suggested by the language server (e.g. "Add missing import", "Extract to function"). /// -/// Returns a numbered list of available actions. Use apply_code_action with the -/// corresponding number to apply one. +/// Returns a numbered list of available actions. Use apply_code_action with the corresponding number to apply one. /// -/// Before using this tool, use read_file or grep to find the exact symbol -/// name and line number. +/// Before using this tool, use read_file or grep to find the exact symbol name and line number. #[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)] pub struct GetCodeActionsToolInput { /// The symbol to get code actions for. diff --git a/crates/agent/src/tools/go_to_definition_tool.rs b/crates/agent/src/tools/go_to_definition_tool.rs index 2061da124b0725928b363647ac35578b0060ae34..2c217ed105a2ef7d3a5c37acc964c9cbc54ff234 100644 --- a/crates/agent/src/tools/go_to_definition_tool.rs +++ b/crates/agent/src/tools/go_to_definition_tool.rs @@ -11,11 +11,9 @@ use serde::{Deserialize, Serialize}; /// Jumps to the definition of a symbol using the language server. /// -/// Returns the file path and line number of the symbol's definition, -/// along with a snippet of the source code at that location. +/// Returns the file path and line number of the symbol's definition, along with a snippet of the source code at that location. /// -/// Before using this tool, use read_file or grep to find the exact symbol -/// name and line number of a usage you want to navigate from. +/// Before using this tool, use read_file or grep to find the exact symbol name and line number of a usage you want to navigate from. #[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)] pub struct GoToDefinitionToolInput { /// The symbol to find the definition of. diff --git a/crates/agent/src/tools/now_tool.rs b/crates/agent/src/tools/now_tool.rs deleted file mode 100644 index d60e4c7f1d6bafe54a71b3d0289b69942adb8d4a..0000000000000000000000000000000000000000 --- a/crates/agent/src/tools/now_tool.rs +++ /dev/null @@ -1,91 +0,0 @@ -use std::sync::Arc; - -use agent_client_protocol::schema as acp; -use chrono::{Local, Utc}; -use gpui::{App, SharedString, Task}; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -use super::deserialize_maybe_stringified; -use crate::{AgentTool, ToolCallEventStream, ToolInput}; - -#[derive(Debug, Serialize, Deserialize, JsonSchema)] -#[serde(rename_all = "snake_case")] -#[schemars(inline)] -pub enum Timezone { - #[serde(alias = "UTC", alias = "Utc")] - Utc, - #[serde(alias = "LOCAL", alias = "Local")] - Local, -} - -/// Returns the current datetime in RFC 3339 format. -/// Only use this tool when the user specifically asks for it or the current task would benefit from knowing the current datetime. -#[derive(Debug, Serialize, Deserialize, JsonSchema)] -pub struct NowToolInput { - /// The timezone to use for the datetime. Use `utc` for UTC, or `local` for the system's local time. - #[serde(deserialize_with = "deserialize_maybe_stringified")] - timezone: Timezone, -} - -pub struct NowTool; - -impl AgentTool for NowTool { - type Input = NowToolInput; - type Output = String; - - const NAME: &'static str = "now"; - - fn kind() -> acp::ToolKind { - acp::ToolKind::Other - } - - fn initial_title( - &self, - _input: Result, - _cx: &mut App, - ) -> SharedString { - "Get current time".into() - } - - fn run( - self: Arc, - input: ToolInput, - _event_stream: ToolCallEventStream, - cx: &mut App, - ) -> Task> { - cx.spawn(async move |_cx| { - let input = input.recv().await.map_err(|e| e.to_string())?; - let now = match input.timezone { - Timezone::Utc => Utc::now().to_rfc3339(), - Timezone::Local => Local::now().to_rfc3339(), - }; - Ok(format!("The current datetime is {now}.")) - }) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use gpui::TestAppContext; - use serde_json::json; - - #[gpui::test] - async fn test_stringified_timezone_input_succeeds(cx: &mut TestAppContext) { - let tool = Arc::new(NowTool); - let (mut sender, input) = ToolInput::::test(); - let (event_stream, _receiver) = ToolCallEventStream::test(); - let task = cx.update(|cx| tool.clone().run(input, event_stream, cx)); - - sender.send_full(json!({ - "timezone": "\"utc\"" - })); - - let result = task.await.unwrap(); - assert!( - result.starts_with("The current datetime is "), - "unexpected output: {result}" - ); - } -} diff --git a/crates/agent/src/tools/rename_tool.rs b/crates/agent/src/tools/rename_tool.rs index 7abc45d6956874304c69bd69def13dba82058f49..ac8fa1dccb26384d3f82a443b00cb68581a0f755 100644 --- a/crates/agent/src/tools/rename_tool.rs +++ b/crates/agent/src/tools/rename_tool.rs @@ -12,12 +12,9 @@ use crate::{AgentTool, ToolCallEventStream, ToolInput}; /// Renames a symbol across the project using the language server. /// -/// This performs a semantic rename, updating all references to the symbol -/// across all files in the project. The language server determines which -/// occurrences to rename based on the symbol's type and scope. +/// This performs a semantic rename, updating all references to the symbol across all files in the project. The language server determines which occurrences to rename based on the symbol's type and scope. /// -/// Before using this tool, use read_file or grep to find the exact symbol -/// name and line number. +/// Before using this tool, use read_file or grep to find the exact symbol name and line number. #[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)] pub struct RenameToolInput { /// The symbol to rename. diff --git a/crates/agent/src/tools/spawn_agent_tool.rs b/crates/agent/src/tools/spawn_agent_tool.rs index 5cb2f8c98cd92fd86d70a33dfce079e9eb4edd0b..32650ede9090425478e9447c36442592b357848c 100644 --- a/crates/agent/src/tools/spawn_agent_tool.rs +++ b/crates/agent/src/tools/spawn_agent_tool.rs @@ -17,7 +17,7 @@ use crate::{AgentTool, ThreadEnvironment, ToolCallEventStream, ToolInput}; /// - Subtasks must be concrete, well-defined, and self-contained. /// - Delegated subtasks must materially advance the main task. /// - Do not duplicate work between your work and delegated subtasks. -/// - Do not use this tool for tasks you could accomplish directly with one or two tool calls. +/// - Do not use this tool for tasks you could accomplish directly with one or two tool calls. For example, don't ask the agent to read a single file and return the contents, you can do this yourself. /// - When you delegate work, focus on coordinating and synthesizing results instead of duplicating the same work yourself. /// - Avoid issuing multiple delegate calls for the same unresolved subproblem unless the new delegated task is genuinely different and necessary. /// - Narrow the delegated ask to the concrete output you need next. diff --git a/crates/agent/src/tools/symbol_locator.rs b/crates/agent/src/tools/symbol_locator.rs index cb38101877ea2a437bc401910af9a340c7108b79..1904e412c6f61ffd92972319116e8587f27dcdd1 100644 --- a/crates/agent/src/tools/symbol_locator.rs +++ b/crates/agent/src/tools/symbol_locator.rs @@ -11,16 +11,13 @@ use text::{Anchor, Point}; /// Identifies a specific symbol (declaration or usage) in the source code. /// -/// Use the file path, line number, and symbol name from file outlines, grep results, -/// or other tool outputs to populate these fields. +/// Use the file path, line number, and symbol name from file outlines, grep results, or other tool outputs to populate these fields. #[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)] pub struct SymbolLocator { - /// The relative path of the file containing the symbol - /// (e.g. "crates/editor/src/editor.rs"). + /// The relative path of the file containing the symbol (e.g. "crates/editor/src/editor.rs"). pub file_path: String, - /// The 1-based line number where the symbol appears. - /// Use the line numbers from file outlines or grep results. + /// The 1-based line number where the symbol appears. Use the line numbers from file outlines or grep results. pub line: u32, /// The name of the symbol (function name, type name, variable name, etc.) diff --git a/crates/agent/src/tools/write_file_tool.rs b/crates/agent/src/tools/write_file_tool.rs index bfd454aba9723f2733dcaeda5732225e76261782..d48d574397e11845071b04417d71a7fb3a999a4e 100644 --- a/crates/agent/src/tools/write_file_tool.rs +++ b/crates/agent/src/tools/write_file_tool.rs @@ -21,10 +21,7 @@ const DEFAULT_UI_TEXT: &str = "Writing file"; /// /// To make granular edits to an existing file, prefer the `edit_file` tool instead. /// -/// Before using this tool: -/// -/// 1. Verify the directory path is correct (only applicable when creating new files): -/// - Use the `list_directory` tool to verify the parent directory exists and is the correct location +/// Before using this tool, verify the directory path is correct (only applicable when creating new files). Use the `list_directory` tool to verify the parent directory exists and is the correct location #[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)] pub struct WriteFileToolInput { /// The full path of the file to create or overwrite in the project. @@ -46,8 +43,7 @@ pub struct WriteFileToolInput { /// pub path: PathBuf, - /// The complete content for the file. - /// This field should contain the entire file content. + /// The entire content for the file. pub content: String, } diff --git a/crates/feature_flags/src/flags.rs b/crates/feature_flags/src/flags.rs index cb21626737625741746eabf22bffe8b902ab35b3..153991d7b22e2de2a278e8504623e402c6073959 100644 --- a/crates/feature_flags/src/flags.rs +++ b/crates/feature_flags/src/flags.rs @@ -35,6 +35,18 @@ impl FeatureFlag for AgentSharingFeatureFlag { } register_feature_flag!(AgentSharingFeatureFlag); +pub struct ExperimentalSystemPromptFeatureFlag; + +impl FeatureFlag for ExperimentalSystemPromptFeatureFlag { + const NAME: &'static str = "experimental-system-prompt"; + type Value = PresenceFlag; + + fn enabled_for_staff() -> bool { + false + } +} +register_feature_flag!(ExperimentalSystemPromptFeatureFlag); + pub struct AgentPanelTerminalFeatureFlag; impl FeatureFlag for AgentPanelTerminalFeatureFlag { diff --git a/crates/settings_ui/src/pages/tool_permissions_setup.rs b/crates/settings_ui/src/pages/tool_permissions_setup.rs index 550b9a3adc6ae0d2e5fb8f65500dab7f25c72e67..ea47ca67cbf8242c602c0e94cad4126ee416a648 100644 --- a/crates/settings_ui/src/pages/tool_permissions_setup.rs +++ b/crates/settings_ui/src/pages/tool_permissions_setup.rs @@ -1404,7 +1404,6 @@ mod tests { "go_to_definition", "grep", "list_directory", - "now", "open", "read_file", "rename_symbol",