mirror of
https://github.com/sourcegit-scm/sourcegit
synced 2025-05-21 04:04:59 +00:00
fix: Ignore the Chain-of-Thought in AI response (#952)
- Improve chat response processing to handle thinking patterns using regular expressions. - Migrate server value by removing trailing '/chat/completions' path.
This commit is contained in:
parent
8cc056d2af
commit
ef2e0a8a56
2 changed files with 78 additions and 10 deletions
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
|
@ -48,16 +49,18 @@ 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();
|
||||||
if (rs.IsSuccess)
|
if (rs.IsSuccess)
|
||||||
{
|
{
|
||||||
|
var hasFirstValidChar = false;
|
||||||
|
var thinkingBuffer = new StringBuilder();
|
||||||
_service.Chat(
|
_service.Chat(
|
||||||
_service.AnalyzeDiffPrompt,
|
_service.AnalyzeDiffPrompt,
|
||||||
$"Here is the `git diff` output: {rs.StdOut}",
|
$"Here is the `git diff` output: {rs.StdOut}",
|
||||||
_cancelToken,
|
_cancelToken,
|
||||||
update =>
|
update =>
|
||||||
{
|
ProcessChatResponse(update, ref hasFirstValidChar, thinkingBuffer,
|
||||||
responseBuilder.Append(update);
|
(responseBuilder, text =>
|
||||||
summaryBuilder.Append(update);
|
_onResponse?.Invoke(
|
||||||
_onResponse?.Invoke("Waiting for pre-file analyzing to complated...\n\n" + responseBuilder.ToString());
|
$"Waiting for pre-file analyzing to completed...\n\n{text}")),
|
||||||
});
|
(summaryBuilder, null)));
|
||||||
}
|
}
|
||||||
|
|
||||||
responseBuilder.Append("\n");
|
responseBuilder.Append("\n");
|
||||||
|
@ -71,15 +74,15 @@ namespace SourceGit.Commands
|
||||||
|
|
||||||
var responseBody = responseBuilder.ToString();
|
var responseBody = responseBuilder.ToString();
|
||||||
var subjectBuilder = new StringBuilder();
|
var subjectBuilder = new StringBuilder();
|
||||||
|
var hasSubjectFirstValidChar = false;
|
||||||
|
var subjectThinkingBuffer = new StringBuilder();
|
||||||
_service.Chat(
|
_service.Chat(
|
||||||
_service.GenerateSubjectPrompt,
|
_service.GenerateSubjectPrompt,
|
||||||
$"Here are the summaries changes:\n{summaryBuilder}",
|
$"Here are the summaries changes:\n{summaryBuilder}",
|
||||||
_cancelToken,
|
_cancelToken,
|
||||||
update =>
|
update =>
|
||||||
{
|
ProcessChatResponse(update, ref hasSubjectFirstValidChar, subjectThinkingBuffer,
|
||||||
subjectBuilder.Append(update);
|
(subjectBuilder, text => _onResponse?.Invoke($"{text}\n\n{responseBody}"))));
|
||||||
_onResponse?.Invoke($"{subjectBuilder}\n\n{responseBody}");
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
@ -87,10 +90,67 @@ namespace SourceGit.Commands
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ProcessChatResponse(
|
||||||
|
string update,
|
||||||
|
ref bool hasFirstValidChar,
|
||||||
|
StringBuilder thinkingBuffer,
|
||||||
|
params (StringBuilder builder, Action<string> callback)[] outputs)
|
||||||
|
{
|
||||||
|
if (!hasFirstValidChar)
|
||||||
|
{
|
||||||
|
update = update.TrimStart();
|
||||||
|
if (string.IsNullOrEmpty(update))
|
||||||
|
return;
|
||||||
|
if (update.StartsWith("<", StringComparison.Ordinal))
|
||||||
|
thinkingBuffer.Append(update);
|
||||||
|
hasFirstValidChar = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (thinkingBuffer.Length > 0)
|
||||||
|
thinkingBuffer.Append(update);
|
||||||
|
|
||||||
|
if (thinkingBuffer.Length > 15)
|
||||||
|
{
|
||||||
|
var match = REG_COT.Match(thinkingBuffer.ToString());
|
||||||
|
if (match.Success)
|
||||||
|
{
|
||||||
|
update = REG_COT.Replace(thinkingBuffer.ToString(), "").TrimStart();
|
||||||
|
if (update.Length > 0)
|
||||||
|
{
|
||||||
|
foreach (var output in outputs)
|
||||||
|
output.builder.Append(update);
|
||||||
|
thinkingBuffer.Clear();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
match = REG_THINK_START.Match(thinkingBuffer.ToString());
|
||||||
|
if (!match.Success)
|
||||||
|
{
|
||||||
|
foreach (var output in outputs)
|
||||||
|
output.builder.Append(thinkingBuffer);
|
||||||
|
thinkingBuffer.Clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (thinkingBuffer.Length == 0)
|
||||||
|
{
|
||||||
|
foreach (var output in outputs)
|
||||||
|
{
|
||||||
|
output.builder.Append(update);
|
||||||
|
output.callback?.Invoke(output.builder.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Models.OpenAIService _service;
|
private Models.OpenAIService _service;
|
||||||
private string _repo;
|
private string _repo;
|
||||||
private List<Models.Change> _changes;
|
private List<Models.Change> _changes;
|
||||||
private CancellationToken _cancelToken;
|
private CancellationToken _cancelToken;
|
||||||
private Action<string> _onResponse;
|
private Action<string> _onResponse;
|
||||||
|
|
||||||
|
private static readonly Regex REG_COT = new(@"^<(think|thought|thinking|thought_chain)>(.*?)</\1>", RegexOptions.Singleline);
|
||||||
|
private static readonly Regex REG_THINK_START = new(@"^<(think|thought|thinking|thought_chain)>", RegexOptions.Singleline);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,15 @@ namespace SourceGit.Models
|
||||||
public string Server
|
public string Server
|
||||||
{
|
{
|
||||||
get => _server;
|
get => _server;
|
||||||
set => SetProperty(ref _server, value);
|
set
|
||||||
|
{
|
||||||
|
// migrate old server value
|
||||||
|
if (!string.IsNullOrEmpty(value) && value.EndsWith("/chat/completions", StringComparison.Ordinal))
|
||||||
|
{
|
||||||
|
value = value.Substring(0, value.Length - "/chat/completions".Length);
|
||||||
|
}
|
||||||
|
SetProperty(ref _server, value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string ApiKey
|
public string ApiKey
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue