diff --git a/crates/agent/src/tool_permissions.rs b/crates/agent/src/tool_permissions.rs index e2b3d6cb5bc..64b88cd5739 100644 --- a/crates/agent/src/tool_permissions.rs +++ b/crates/agent/src/tool_permissions.rs @@ -580,6 +580,7 @@ mod tests { inline_assistant_model: None, inline_assistant_use_streaming_tools: false, commit_message_model: None, + commit_message_instructions: None, thread_summary_model: None, inline_alternatives: vec![], favorite_models: vec![], diff --git a/crates/agent_settings/src/agent_settings.rs b/crates/agent_settings/src/agent_settings.rs index d7b9d0ed018..c5ca601f1b4 100644 --- a/crates/agent_settings/src/agent_settings.rs +++ b/crates/agent_settings/src/agent_settings.rs @@ -150,6 +150,7 @@ pub struct AgentSettings { pub inline_assistant_model: Option, pub inline_assistant_use_streaming_tools: bool, pub commit_message_model: Option, + pub commit_message_instructions: Option, pub thread_summary_model: Option, pub inline_alternatives: Vec, pub favorite_models: Vec, @@ -649,6 +650,7 @@ impl Settings for AgentSettings { .inline_assistant_use_streaming_tools .unwrap_or(true), commit_message_model: agent.commit_message_model, + commit_message_instructions: agent.commit_message_instructions, thread_summary_model: agent.thread_summary_model, inline_alternatives: agent.inline_alternatives.unwrap_or_default(), favorite_models: agent.favorite_models, diff --git a/crates/agent_ui/src/agent_ui.rs b/crates/agent_ui/src/agent_ui.rs index ecaef031bac..946ccf8f34f 100644 --- a/crates/agent_ui/src/agent_ui.rs +++ b/crates/agent_ui/src/agent_ui.rs @@ -860,6 +860,7 @@ mod tests { inline_assistant_model: None, inline_assistant_use_streaming_tools: false, commit_message_model: None, + commit_message_instructions: None, thread_summary_model: None, inline_alternatives: vec![], favorite_models: vec![], diff --git a/crates/git_ui/src/git_panel.rs b/crates/git_ui/src/git_panel.rs index b58a7572ac9..65f5e12759a 100644 --- a/crates/git_ui/src/git_panel.rs +++ b/crates/git_ui/src/git_panel.rs @@ -2644,6 +2644,7 @@ impl GitPanel { prompt: &str, user_agents_md: Option<&str>, rules_content: Option<&str>, + instructions: Option<&str>, subject: &str, diff_text: &str, ) -> String { @@ -2663,6 +2664,14 @@ impl GitPanel { None => String::new(), }; + let instructions_section = match instructions { + Some(instructions) if !instructions.trim().is_empty() => format!( + "\n\nThe user has provided the following instructions for writing commit messages that you should follow:\n\ + \n{instructions}\n\n" + ), + _ => String::new(), + }; + let subject_section = if subject.trim().is_empty() { String::new() } else { @@ -2670,7 +2679,7 @@ impl GitPanel { }; format!( - "{prompt}{user_agents_md_section}{rules_section}{subject_section}\nHere are the changes in this commit:\n{diff_text}" + "{prompt}{user_agents_md_section}{rules_section}{instructions_section}{subject_section}\nHere are the changes in this commit:\n{diff_text}" ) } @@ -2701,6 +2710,9 @@ impl GitPanel { }); let temperature = AgentSettings::temperature_for_model(&model, cx); + let instructions = AgentSettings::get_global(cx) + .commit_message_instructions + .clone(); let project = self.project.clone(); let repo_work_dir = repo.read(cx).work_directory_abs_path.clone(); @@ -2762,6 +2774,7 @@ impl GitPanel { &prompt, user_agents_md.as_deref(), rules_content.as_deref(), + instructions.as_deref(), &subject, &diff_text, ); @@ -8721,18 +8734,36 @@ mod tests { "Write a commit message.", Some("Use terse commit messages."), Some("Use the git_ui prefix."), + Some("Follow the configured commit message format."), "Update generated message", "diff --git a/file b/file", ); assert!(prompt.contains("Use terse commit messages.")); assert!(prompt.contains("Use the git_ui prefix.")); + assert!(prompt.contains("Follow the configured commit message format.")); assert!(prompt.contains("Update generated message")); assert!(prompt.contains("diff --git a/file b/file")); let user_agents_md_index = prompt.find("").unwrap(); let project_rules_index = prompt.find("").unwrap(); + let instructions_index = prompt.find("").unwrap(); assert!(user_agents_md_index < project_rules_index); + assert!(project_rules_index < instructions_index); + } + + #[test] + fn test_commit_message_prompt_omits_blank_instructions() { + let prompt = GitPanel::build_commit_message_prompt( + "Write a commit message.", + None, + None, + Some(" \n "), + "", + "diff --git a/file b/file", + ); + + assert!(!prompt.contains("")); } #[gpui::test] diff --git a/crates/settings_content/src/agent.rs b/crates/settings_content/src/agent.rs index 917ca5e0530..66972136021 100644 --- a/crates/settings_content/src/agent.rs +++ b/crates/settings_content/src/agent.rs @@ -131,6 +131,9 @@ pub struct AgentSettingsContent { pub inline_assistant_use_streaming_tools: Option, /// Model to use for generating git commit messages. Defaults to default_model when not specified. pub commit_message_model: Option, + /// Custom instructions to include in the prompt when generating git commit messages. + /// Applied in addition to any project rules files (such as `.rules` or `AGENTS.md`). + pub commit_message_instructions: Option, /// Model to use for generating thread summaries. Defaults to default_model when not specified. pub thread_summary_model: Option, /// Additional models with which to generate alternatives when performing inline assists. diff --git a/docs/src/ai/agent-settings.md b/docs/src/ai/agent-settings.md index dacd149ca62..51de506c47f 100644 --- a/docs/src/ai/agent-settings.md +++ b/docs/src/ai/agent-settings.md @@ -62,6 +62,20 @@ You can assign distinct and specific models for the following AI-powered feature > If a custom model isn't set for one of these features, they automatically fall back to using the default model. +### Commit Message Instructions {#commit-message-instructions} + +You can provide custom instructions that are included in the prompt whenever a Git commit message is generated. Unlike rules files (such as `.rules` or `AGENTS.md`), these instructions apply only to commit message generation: + +```json [settings] +{ + "agent": { + "commit_message_instructions": "Use the Conventional Commits format: (): ." + } +} +``` + +These instructions are sent in addition to any project rules files that are present. + ### Alternative Models for Inline Assists {#alternative-assists} With the Inline Assistant in particular, you can send the same prompt to multiple models at once. diff --git a/docs/src/git.md b/docs/src/git.md index 1f9dc4fb9ac..53c7227dbb3 100644 --- a/docs/src/git.md +++ b/docs/src/git.md @@ -293,6 +293,18 @@ See [Feature-specific models](./ai/agent-settings.md#feature-specific-models) fo To add custom commit instructions for the model, use the global `AGENTS.md` file located `~/.config/zed/AGENTS.md` on macOS and Linux, `%APPDATA%\Zed\AGENTS.md` on Windows. +To add custom instructions that apply only to commit message generation, use the `commit_message_instructions` field in your agent settings: + +```json [settings] +{ + "agent": { + "commit_message_instructions": "Use the Conventional Commits format: (): ." + } +} +``` + +These instructions are sent to the model in addition to any project rules files (such as `.rules` or `AGENTS.md`). To add instructions that apply to both commit messages and the agent more broadly, use the global `AGENTS.md` file located `~/.config/zed/AGENTS.md` on macOS and Linux, `%APPDATA%\Zed\AGENTS.md` on Windows. + > Before Zed v1.4.0, this was done through the Rules Library, which has been removed. > See [the "Migrating to Skills" docs](./ai/rules.md#migrating-to-skills) in the Rules page for more information.