mirror of
https://github.com/sourcegit-scm/sourcegit.git
synced 2024-12-24 20:57:19 -08:00
code_review: PR #596
- Add `ViewModels.Preference.PrepareOpenAIPrompt()` method to generate default prompt instead of a const fallback value. Therefore, it is more convenient for us to modify the default value in the Preference dialog. - Modify the default prompts. Rename `SubjectPrompt` to `GenerateSubjectPrompt`. Rename `SummaryPrompt` to `AnalyzeDiffPrompt`. - Rewrite the way to build OpenAI user content for subject generation Signed-off-by: leo <longshuang@msn.cn>
This commit is contained in:
parent
2f68aed817
commit
12bb915bd8
5 changed files with 75 additions and 94 deletions
|
@ -10,33 +10,6 @@ namespace SourceGit.Commands
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class GenerateCommitMessage
|
public class GenerateCommitMessage
|
||||||
{
|
{
|
||||||
private const string DEFAULT_SUMMARY_PROMPT = """
|
|
||||||
You are an expert developer specialist in creating commits.
|
|
||||||
Provide a super concise one sentence overall changes summary of the user `git diff` output following strictly the next rules:
|
|
||||||
- Do not use any code snippets, imports, file routes or bullets points.
|
|
||||||
- Do not mention the route of file that has been change.
|
|
||||||
- Simply describe the MAIN GOAL of the changes.
|
|
||||||
- Output directly the summary in plain text.
|
|
||||||
""";
|
|
||||||
|
|
||||||
private const string DEFAULT_SUBJECT_PROMPT = """
|
|
||||||
You are an expert developer specialist in creating commits messages.
|
|
||||||
Your only goal is to retrieve a single commit message.
|
|
||||||
Based on the provided user changes, combine them in ONE SINGLE commit message retrieving the global idea, following strictly the next rules:
|
|
||||||
- Assign the commit {type} according to the next conditions:
|
|
||||||
feat: Only when adding a new feature.
|
|
||||||
fix: When fixing a bug.
|
|
||||||
docs: When updating documentation.
|
|
||||||
style: When changing elements styles or design and/or making changes to the code style (formatting, missing semicolons, etc.) without changing the code logic.
|
|
||||||
test: When adding or updating tests.
|
|
||||||
chore: When making changes to the build process or auxiliary tools and libraries.
|
|
||||||
revert: When undoing a previous commit.
|
|
||||||
refactor: When restructuring code without changing its external behavior, or is any of the other refactor types.
|
|
||||||
- Do not add any issues numeration, explain your output nor introduce your answer.
|
|
||||||
- Output directly only one commit message in plain text with the next format: {type}: {commit_message}.
|
|
||||||
- Be as concise as possible, keep the message under 50 characters.
|
|
||||||
""";
|
|
||||||
|
|
||||||
public class GetDiffContent : Command
|
public class GetDiffContent : Command
|
||||||
{
|
{
|
||||||
public GetDiffContent(string repo, Models.DiffOption opt)
|
public GetDiffContent(string repo, Models.DiffOption opt)
|
||||||
|
@ -59,31 +32,36 @@ namespace SourceGit.Commands
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var summaries = new List<string>();
|
var summarybuilder = new StringBuilder();
|
||||||
|
var bodyBuilder = new StringBuilder();
|
||||||
foreach (var change in _changes)
|
foreach (var change in _changes)
|
||||||
{
|
{
|
||||||
if (_cancelToken.IsCancellationRequested)
|
if (_cancelToken.IsCancellationRequested)
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
_onProgress?.Invoke($"Analyzing {change.Path}...");
|
_onProgress?.Invoke($"Analyzing {change.Path}...");
|
||||||
|
|
||||||
var summary = GenerateChangeSummary(change);
|
var summary = GenerateChangeSummary(change);
|
||||||
summaries.Add(summary);
|
summarybuilder.Append("- ");
|
||||||
|
summarybuilder.Append(summary);
|
||||||
|
summarybuilder.Append("(file: ");
|
||||||
|
summarybuilder.Append(change.Path);
|
||||||
|
summarybuilder.Append(")");
|
||||||
|
summarybuilder.AppendLine();
|
||||||
|
|
||||||
|
bodyBuilder.Append("- ");
|
||||||
|
bodyBuilder.Append(summary);
|
||||||
|
bodyBuilder.AppendLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_cancelToken.IsCancellationRequested)
|
if (_cancelToken.IsCancellationRequested)
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
_onProgress?.Invoke($"Generating commit message...");
|
_onProgress?.Invoke($"Generating commit message...");
|
||||||
var builder = new StringBuilder();
|
|
||||||
builder.Append(GenerateSubject(string.Join("", summaries)));
|
|
||||||
builder.Append("\n");
|
|
||||||
foreach (var summary in summaries)
|
|
||||||
{
|
|
||||||
builder.Append("\n- ");
|
|
||||||
builder.Append(summary.Trim());
|
|
||||||
}
|
|
||||||
|
|
||||||
return builder.ToString();
|
var body = bodyBuilder.ToString();
|
||||||
|
var subject = GenerateSubject(summarybuilder.ToString());
|
||||||
|
return string.Format("{0}\n\n{1}", subject, body);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
@ -97,12 +75,7 @@ namespace SourceGit.Commands
|
||||||
var rs = new GetDiffContent(_repo, new Models.DiffOption(change, false)).ReadToEnd();
|
var rs = new GetDiffContent(_repo, new Models.DiffOption(change, false)).ReadToEnd();
|
||||||
var diff = rs.IsSuccess ? rs.StdOut : "unknown change";
|
var diff = rs.IsSuccess ? rs.StdOut : "unknown change";
|
||||||
|
|
||||||
var prompt = string.IsNullOrWhiteSpace(Models.OpenAI.SummaryPrompt)
|
var rsp = Models.OpenAI.Chat(Models.OpenAI.AnalyzeDiffPrompt, $"Here is the `git diff` output: {diff}", _cancelToken);
|
||||||
? DEFAULT_SUMMARY_PROMPT
|
|
||||||
: Models.OpenAI.SummaryPrompt;
|
|
||||||
|
|
||||||
var rsp = Models.OpenAI.Chat(prompt, $"Here is the `git diff` output: {diff}", _cancelToken);
|
|
||||||
|
|
||||||
if (rsp != null && rsp.Choices.Count > 0)
|
if (rsp != null && rsp.Choices.Count > 0)
|
||||||
return rsp.Choices[0].Message.Content;
|
return rsp.Choices[0].Message.Content;
|
||||||
|
|
||||||
|
@ -111,12 +84,7 @@ namespace SourceGit.Commands
|
||||||
|
|
||||||
private string GenerateSubject(string summary)
|
private string GenerateSubject(string summary)
|
||||||
{
|
{
|
||||||
var prompt = string.IsNullOrWhiteSpace(Models.OpenAI.SubjectPrompt)
|
var rsp = Models.OpenAI.Chat(Models.OpenAI.GenerateSubjectPrompt, $"Here are the summaries changes:\n{summary}", _cancelToken);
|
||||||
? DEFAULT_SUBJECT_PROMPT
|
|
||||||
: Models.OpenAI.SubjectPrompt;
|
|
||||||
|
|
||||||
var rsp = Models.OpenAI.Chat(prompt, $"Here are the summaries changes: {summary}", _cancelToken);
|
|
||||||
|
|
||||||
if (rsp != null && rsp.Choices.Count > 0)
|
if (rsp != null && rsp.Choices.Count > 0)
|
||||||
return rsp.Choices[0].Message.Content;
|
return rsp.Choices[0].Message.Content;
|
||||||
|
|
||||||
|
|
|
@ -94,13 +94,13 @@ namespace SourceGit.Models
|
||||||
set;
|
set;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string SubjectPrompt
|
public static string AnalyzeDiffPrompt
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
set;
|
set;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string SummaryPrompt
|
public static string GenerateSubjectPrompt
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
set;
|
set;
|
||||||
|
|
|
@ -400,34 +400,11 @@
|
||||||
<x:String x:Key="Text.Period.YearsAgo" xml:space="preserve">{0} years ago</x:String>
|
<x:String x:Key="Text.Period.YearsAgo" xml:space="preserve">{0} years ago</x:String>
|
||||||
<x:String x:Key="Text.Preference" xml:space="preserve">Preference</x:String>
|
<x:String x:Key="Text.Preference" xml:space="preserve">Preference</x:String>
|
||||||
<x:String x:Key="Text.Preference.AI" xml:space="preserve">OPEN AI</x:String>
|
<x:String x:Key="Text.Preference.AI" xml:space="preserve">OPEN AI</x:String>
|
||||||
<x:String x:Key="Text.Preference.AI.Server" xml:space="preserve">Server</x:String>
|
<x:String x:Key="Text.Preference.AI.AnalyzeDiffPrompt" xml:space="preserve">Analyze Diff Prompt</x:String>
|
||||||
<x:String x:Key="Text.Preference.AI.ApiKey" xml:space="preserve">API Key</x:String>
|
<x:String x:Key="Text.Preference.AI.ApiKey" xml:space="preserve">API Key</x:String>
|
||||||
|
<x:String x:Key="Text.Preference.AI.GenerateSubjectPrompt" xml:space="preserve">Generate Subject Prompt</x:String>
|
||||||
<x:String x:Key="Text.Preference.AI.Model" xml:space="preserve">Model</x:String>
|
<x:String x:Key="Text.Preference.AI.Model" xml:space="preserve">Model</x:String>
|
||||||
<x:String x:Key="Text.Preference.AI.SummaryPrompt" xml:space="preserve">Summary Prompt</x:String>
|
<x:String x:Key="Text.Preference.AI.Server" xml:space="preserve">Server</x:String>
|
||||||
<x:String x:Key="Text.Preference.AI.SubjectPrompt" xml:space="preserve">Subject Prompt</x:String>
|
|
||||||
<x:String x:Key="Text.Preference.AI.SummaryPromptHint" xml:space="preserve">You are an expert developer specialist in creating commits.
|
|
||||||
Provide a super concise one sentence overall changes summary of the user `git diff` output following strictly the next rules:
|
|
||||||
- Do not use any code snippets, imports, file routes or bullets points.
|
|
||||||
- Do not mention the route of file that has been change.
|
|
||||||
- Simply describe the MAIN GOAL of the changes.
|
|
||||||
- Output directly the summary in plain text.
|
|
||||||
</x:String>
|
|
||||||
<x:String x:Key="Text.Preference.AI.SubjectPromptHint" xml:space="preserve">You are an expert developer specialist in creating commits messages.
|
|
||||||
Your only goal is to retrieve a single commit message.
|
|
||||||
Based on the provided user changes, combine them in ONE SINGLE commit message retrieving the global idea, following strictly the next rules:
|
|
||||||
- Assign the commit {type} according to the next conditions:
|
|
||||||
feat: Only when adding a new feature.
|
|
||||||
fix: When fixing a bug.
|
|
||||||
docs: When updating documentation.
|
|
||||||
style: When changing elements styles or design and/or making changes to the code style (formatting, missing semicolons, etc.) without changing the code logic.
|
|
||||||
test: When adding or updating tests.
|
|
||||||
chore: When making changes to the build process or auxiliary tools and libraries.
|
|
||||||
revert: When undoing a previous commit.
|
|
||||||
refactor: When restructuring code without changing its external behavior, or is any of the other refactor types.
|
|
||||||
- Do not add any issues numeration, explain your output nor introduce your answer.
|
|
||||||
- Output directly only one commit message in plain text with the next format: {type}: {commit_message}.
|
|
||||||
- Be as concise as possible, keep the message under 50 characters.
|
|
||||||
</x:String>
|
|
||||||
<x:String x:Key="Text.Preference.Appearance" xml:space="preserve">APPEARANCE</x:String>
|
<x:String x:Key="Text.Preference.Appearance" xml:space="preserve">APPEARANCE</x:String>
|
||||||
<x:String x:Key="Text.Preference.Appearance.DefaultFont" xml:space="preserve">Default Font</x:String>
|
<x:String x:Key="Text.Preference.Appearance.DefaultFont" xml:space="preserve">Default Font</x:String>
|
||||||
<x:String x:Key="Text.Preference.Appearance.DefaultFontSize" xml:space="preserve">Default Font Size</x:String>
|
<x:String x:Key="Text.Preference.Appearance.DefaultFontSize" xml:space="preserve">Default Font Size</x:String>
|
||||||
|
|
|
@ -25,6 +25,7 @@ namespace SourceGit.ViewModels
|
||||||
_instance.PrepareGit();
|
_instance.PrepareGit();
|
||||||
_instance.PrepareShellOrTerminal();
|
_instance.PrepareShellOrTerminal();
|
||||||
_instance.PrepareWorkspaces();
|
_instance.PrepareWorkspaces();
|
||||||
|
_instance.PrepareOpenAIPrompt();
|
||||||
|
|
||||||
return _instance;
|
return _instance;
|
||||||
}
|
}
|
||||||
|
@ -315,27 +316,27 @@ namespace SourceGit.ViewModels
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string OpenAISubjectPrompt
|
public string OpenAIAnalyzeDiffPrompt
|
||||||
{
|
{
|
||||||
get => Models.OpenAI.SubjectPrompt;
|
get => Models.OpenAI.AnalyzeDiffPrompt;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value != Models.OpenAI.SubjectPrompt)
|
if (value != Models.OpenAI.AnalyzeDiffPrompt)
|
||||||
{
|
{
|
||||||
Models.OpenAI.SubjectPrompt = value;
|
Models.OpenAI.AnalyzeDiffPrompt = value;
|
||||||
OnPropertyChanged();
|
OnPropertyChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string OpenAISummaryPrompt
|
public string OpenAIGenerateSubjectPrompt
|
||||||
{
|
{
|
||||||
get => Models.OpenAI.SummaryPrompt;
|
get => Models.OpenAI.GenerateSubjectPrompt;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value != Models.OpenAI.SummaryPrompt)
|
if (value != Models.OpenAI.GenerateSubjectPrompt)
|
||||||
{
|
{
|
||||||
Models.OpenAI.SummaryPrompt = value;
|
Models.OpenAI.GenerateSubjectPrompt = value;
|
||||||
OnPropertyChanged();
|
OnPropertyChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -553,6 +554,45 @@ namespace SourceGit.ViewModels
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void PrepareOpenAIPrompt()
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(Models.OpenAI.AnalyzeDiffPrompt))
|
||||||
|
{
|
||||||
|
Models.OpenAI.AnalyzeDiffPrompt = """
|
||||||
|
You are an expert developer specialist in creating commits.
|
||||||
|
Provide a super concise one sentence overall changes summary of the user `git diff` output following strictly the next rules:
|
||||||
|
- Do not use any code snippets, imports, file routes or bullets points.
|
||||||
|
- Do not mention the route of file that has been change.
|
||||||
|
- Write clear, concise, and descriptive messages that explain the MAIN GOAL made of the changes.
|
||||||
|
- Use the present tense and active voice in the message, for example, "Fix bug" instead of "Fixed bug.".
|
||||||
|
- Use the imperative mood, which gives the message a sense of command, e.g. "Add feature" instead of "Added feature".
|
||||||
|
- Avoid using general terms like "update" or "change", be specific about what was updated or changed.
|
||||||
|
- Avoid using terms like "The main goal of", just output directly the summary in plain text
|
||||||
|
""";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(Models.OpenAI.GenerateSubjectPrompt))
|
||||||
|
{
|
||||||
|
Models.OpenAI.GenerateSubjectPrompt = """
|
||||||
|
You are an expert developer specialist in creating commits messages.
|
||||||
|
Your only goal is to retrieve a single commit message.
|
||||||
|
Based on the provided user changes, combine them in ONE SINGLE commit message retrieving the global idea, following strictly the next rules:
|
||||||
|
- Assign the commit {type} according to the next conditions:
|
||||||
|
feat: Only when adding a new feature.
|
||||||
|
fix: When fixing a bug.
|
||||||
|
docs: When updating documentation.
|
||||||
|
style: When changing elements styles or design and/or making changes to the code style (formatting, missing semicolons, etc.) without changing the code logic.
|
||||||
|
test: When adding or updating tests.
|
||||||
|
chore: When making changes to the build process or auxiliary tools and libraries.
|
||||||
|
revert: When undoing a previous commit.
|
||||||
|
refactor: When restructuring code without changing its external behavior, or is any of the other refactor types.
|
||||||
|
- Do not add any issues numeration, explain your output nor introduce your answer.
|
||||||
|
- Output directly only one commit message in plain text with the next format: {type}: {commit_message}.
|
||||||
|
- Be as concise as possible, keep the message under 50 characters.
|
||||||
|
""";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private RepositoryNode FindNodeRecursive(string id, List<RepositoryNode> collection)
|
private RepositoryNode FindNodeRecursive(string id, List<RepositoryNode> collection)
|
||||||
{
|
{
|
||||||
foreach (var node in collection)
|
foreach (var node in collection)
|
||||||
|
|
|
@ -499,31 +499,27 @@
|
||||||
Text="{Binding OpenAIApiKey, Mode=TwoWay}"/>
|
Text="{Binding OpenAIApiKey, Mode=TwoWay}"/>
|
||||||
|
|
||||||
<TextBlock Grid.Row="3" Grid.Column="0"
|
<TextBlock Grid.Row="3" Grid.Column="0"
|
||||||
Text="{DynamicResource Text.Preference.AI.SubjectPrompt}"
|
Text="{DynamicResource Text.Preference.AI.AnalyzeDiffPrompt}"
|
||||||
HorizontalAlignment="Right"
|
HorizontalAlignment="Right"
|
||||||
Margin="0,0,16,0"/>
|
Margin="0,0,16,0"/>
|
||||||
|
|
||||||
<TextBox Grid.Row="3" Grid.Column="1"
|
<TextBox Grid.Row="3" Grid.Column="1"
|
||||||
Height="120"
|
Height="120"
|
||||||
CornerRadius="3"
|
CornerRadius="3"
|
||||||
VerticalContentAlignment="Top"
|
VerticalContentAlignment="Top"
|
||||||
Text="{Binding OpenAISubjectPrompt, Mode=TwoWay}"
|
Text="{Binding OpenAIAnalyzeDiffPrompt, Mode=TwoWay}"
|
||||||
AcceptsReturn="true"
|
AcceptsReturn="true"
|
||||||
Watermark="{DynamicResource Text.Preference.AI.SubjectPromptHint}"
|
|
||||||
TextWrapping="Wrap"/>
|
TextWrapping="Wrap"/>
|
||||||
|
|
||||||
<TextBlock Grid.Row="4" Grid.Column="0"
|
<TextBlock Grid.Row="4" Grid.Column="0"
|
||||||
Text="{DynamicResource Text.Preference.AI.SummaryPrompt}"
|
Text="{DynamicResource Text.Preference.AI.GenerateSubjectPrompt}"
|
||||||
HorizontalAlignment="Right"
|
HorizontalAlignment="Right"
|
||||||
Margin="0,0,16,0"/>
|
Margin="0,0,16,0"/>
|
||||||
|
|
||||||
<TextBox Grid.Row="4" Grid.Column="1"
|
<TextBox Grid.Row="4" Grid.Column="1"
|
||||||
Height="120"
|
Height="120"
|
||||||
CornerRadius="3"
|
CornerRadius="3"
|
||||||
VerticalContentAlignment="Top"
|
VerticalContentAlignment="Top"
|
||||||
Text="{Binding OpenAISummaryPrompt, Mode=TwoWay}"
|
Text="{Binding OpenAIGenerateSubjectPrompt, Mode=TwoWay}"
|
||||||
AcceptsReturn="true"
|
AcceptsReturn="true"
|
||||||
Watermark="{DynamicResource Text.Preference.AI.SummaryPromptHint}"
|
|
||||||
TextWrapping="Wrap"/>
|
TextWrapping="Wrap"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
Loading…
Reference in a new issue