mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-08-11 17:32:11 +00:00
extracting the raw JSON from the AI response and make sure its not a math or md block
This commit is contained in:
parent
05412eb77f
commit
68866ecb8a
@ -17,6 +17,7 @@ public partial class ContentBlockComponent : MSGComponentBase, IAsyncDisposable
|
||||
private const string HTML_SELF_CLOSING_TAG = "/>";
|
||||
private const string CODE_FENCE_MARKER_BACKTICK = "```";
|
||||
private const string CODE_FENCE_MARKER_TILDE = "~~~";
|
||||
private const string CHART_CODE_FENCE_LANGUAGE = "aistudio-chart";
|
||||
private const string MATH_BLOCK_MARKER_DOLLAR = "$$";
|
||||
private const string MATH_BLOCK_MARKER_BRACKET_OPEN = """\[""";
|
||||
private const string MATH_BLOCK_MARKER_BRACKET_CLOSE = """\]""";
|
||||
@ -336,6 +337,20 @@ public partial class ContentBlockComponent : MSGComponentBase, IAsyncDisposable
|
||||
}
|
||||
|
||||
var trimmedLine = TrimWhitespace(normalizedSpan[lineStart..lineEnd]);
|
||||
if (activeMathBlockFenceType is MathBlockFenceType.NONE
|
||||
&& activeCodeFenceMarker == '\0'
|
||||
&& TryGetChartFenceMarker(trimmedLine, out var chartFenceMarker)
|
||||
&& TryFindClosingCodeFence(normalizedSpan, nextLineStart, chartFenceMarker, out var chartContentEnd, out var afterChartFence))
|
||||
{
|
||||
AddMarkdownSegment(markdownSegmentStart, lineStart);
|
||||
var (start, end) = TrimLineBreaks(normalizedSpan, nextLineStart, chartContentEnd);
|
||||
var chartJson = normalized.Substring(start, end - start);
|
||||
segments.Add(new(MarkdownRenderSegmentType.CHART, start, end - start, ChartBlockParser.Parse(chartJson)));
|
||||
markdownSegmentStart = afterChartFence;
|
||||
lineStart = afterChartFence;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (activeMathBlockFenceType is MathBlockFenceType.NONE && TryUpdateCodeFenceState(trimmedLine, ref activeCodeFenceMarker))
|
||||
{
|
||||
lineStart = nextLineStart;
|
||||
@ -463,6 +478,48 @@ public partial class ContentBlockComponent : MSGComponentBase, IAsyncDisposable
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool TryGetChartFenceMarker(ReadOnlySpan<char> trimmedLine, out char fenceMarker)
|
||||
{
|
||||
fenceMarker = '\0';
|
||||
if (trimmedLine.SequenceEqual($"{CODE_FENCE_MARKER_BACKTICK}{CHART_CODE_FENCE_LANGUAGE}".AsSpan()))
|
||||
fenceMarker = '`';
|
||||
else if (trimmedLine.SequenceEqual($"{CODE_FENCE_MARKER_TILDE}{CHART_CODE_FENCE_LANGUAGE}".AsSpan()))
|
||||
fenceMarker = '~';
|
||||
|
||||
return fenceMarker != '\0';
|
||||
}
|
||||
|
||||
private static bool TryFindClosingCodeFence(ReadOnlySpan<char> text, int searchStart, char fenceMarker, out int contentEnd, out int afterFence)
|
||||
{
|
||||
contentEnd = 0;
|
||||
afterFence = 0;
|
||||
var closingFence = fenceMarker == '`' ? CODE_FENCE_MARKER_BACKTICK : CODE_FENCE_MARKER_TILDE;
|
||||
|
||||
for (var lineStart = searchStart; lineStart < text.Length;)
|
||||
{
|
||||
var lineEnd = lineStart;
|
||||
while (lineEnd < text.Length && text[lineEnd] is not '\r' and not '\n')
|
||||
lineEnd++;
|
||||
|
||||
var nextLineStart = lineEnd;
|
||||
if (nextLineStart < text.Length && text[nextLineStart] == '\r')
|
||||
nextLineStart++;
|
||||
if (nextLineStart < text.Length && text[nextLineStart] == '\n')
|
||||
nextLineStart++;
|
||||
|
||||
if (TrimWhitespace(text[lineStart..lineEnd]).SequenceEqual(closingFence.AsSpan()))
|
||||
{
|
||||
contentEnd = lineStart;
|
||||
afterFence = nextLineStart;
|
||||
return true;
|
||||
}
|
||||
|
||||
lineStart = nextLineStart;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static ReadOnlySpan<char> TrimWhitespace(ReadOnlySpan<char> text)
|
||||
{
|
||||
var start = 0;
|
||||
@ -492,6 +549,7 @@ public partial class ContentBlockComponent : MSGComponentBase, IAsyncDisposable
|
||||
{
|
||||
MARKDOWN,
|
||||
MATH_BLOCK,
|
||||
CHART,
|
||||
}
|
||||
|
||||
private enum MathBlockFenceType
|
||||
@ -506,7 +564,7 @@ public partial class ContentBlockComponent : MSGComponentBase, IAsyncDisposable
|
||||
public static readonly MarkdownRenderPlan EMPTY = new(string.Empty, []);
|
||||
}
|
||||
|
||||
private sealed class MarkdownRenderSegment(MarkdownRenderSegmentType type, int start, int length)
|
||||
private sealed class MarkdownRenderSegment(MarkdownRenderSegmentType type, int start, int length, ChartBlockParseResult? chartResult = null)
|
||||
{
|
||||
private string? cachedContent;
|
||||
|
||||
@ -516,6 +574,8 @@ public partial class ContentBlockComponent : MSGComponentBase, IAsyncDisposable
|
||||
|
||||
public int Length { get; } = length;
|
||||
|
||||
public ChartBlockParseResult? ChartResult { get; } = chartResult;
|
||||
|
||||
public int RenderKey { get; } = HashCode.Combine(type, start, length);
|
||||
|
||||
public string GetContent(string source)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user