mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-10-15 21:33:47 +00:00
Allow reading web content into assistants (#63)
This commit is contained in:
1 parent
2cea53d2a9
commit
4cb49d9f27
36 files changed
+1127
-24
No files matched your search
@@ -0,0 +1,57 @@
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
|
||||
using HtmlAgilityPack;
|
||||
|
||||
using ReverseMarkdown;
|
||||
|
||||
namespace AIStudio.Tools;
|
||||
|
||||
public sealed class HTMLParser
|
||||
{
|
||||
private static readonly Config MARKDOWN_PARSER_CONFIG = new()
|
||||
{
|
||||
UnknownTags = Config.UnknownTagsOption.Bypass,
|
||||
RemoveComments = true,
|
||||
SmartHrefHandling = true
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Loads the web content from the specified URL.
|
||||
/// </summary>
|
||||
/// <param name="url">The URL of the web page.</param>
|
||||
/// <returns>The web content as text.</returns>
|
||||
public async Task<string> LoadWebContentText(Uri url)
|
||||
{
|
||||
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30));
|
||||
var parser = new HtmlWeb();
|
||||
var doc = await parser.LoadFromWebAsync(url, Encoding.UTF8, new NetworkCredential(), cts.Token);
|
||||
return doc.ParsedText;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads the web content from the specified URL and returns it as an HTML string.
|
||||
/// </summary>
|
||||
/// <param name="url">The URL of the web page.</param>
|
||||
/// <returns>The web content as an HTML string.</returns>
|
||||
public async Task<string> LoadWebContentHTML(Uri url)
|
||||
{
|
||||
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30));
|
||||
var parser = new HtmlWeb();
|
||||
var doc = await parser.LoadFromWebAsync(url, Encoding.UTF8, new NetworkCredential(), cts.Token);
|
||||
var innerHtml = doc.DocumentNode.InnerHtml;
|
||||
|
||||
return innerHtml;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts HTML content to the Markdown format.
|
||||
/// </summary>
|
||||
/// <param name="html">The HTML content to parse.</param>
|
||||
/// <returns>The converted Markdown content.</returns>
|
||||
public string ParseToMarkdown(string html)
|
||||
{
|
||||
var markdownConverter = new Converter(MARKDOWN_PARSER_CONFIG);
|
||||
return markdownConverter.Convert(html);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
using System.Text;
|
||||
|
||||
namespace AIStudio.Tools;
|
||||
|
||||
public sealed class Process<T> where T : struct, Enum
|
||||
{
|
||||
public static readonly Process<T> INSTANCE = new();
|
||||
|
||||
private readonly Dictionary<T, ProcessStepValue> stepsData = [];
|
||||
private readonly int min = int.MaxValue;
|
||||
private readonly int max = int.MinValue;
|
||||
private readonly string[] labels;
|
||||
|
||||
private Process()
|
||||
{
|
||||
var values = Enum.GetValues<T>();
|
||||
this.labels = new string[values.Length];
|
||||
|
||||
for (var i = 0; i < values.Length; i++)
|
||||
{
|
||||
var value = values[i];
|
||||
var stepValue = Convert.ToInt32(value);
|
||||
var stepName = DeriveName(value);
|
||||
|
||||
this.labels[i] = stepName;
|
||||
this.stepsData[value] = new ProcessStepValue(stepValue, stepName);
|
||||
|
||||
if (stepValue < this.min)
|
||||
this.min = stepValue;
|
||||
|
||||
if (stepValue > this.max)
|
||||
this.max = stepValue;
|
||||
}
|
||||
}
|
||||
|
||||
private static string DeriveName(T value)
|
||||
{
|
||||
var text = value.ToString();
|
||||
if (!text.Contains('_'))
|
||||
{
|
||||
text = text.ToLowerInvariant();
|
||||
text = char.ToUpperInvariant(text[0]) + text[1..];
|
||||
}
|
||||
else
|
||||
{
|
||||
var parts = text.Split('_');
|
||||
var sb = new StringBuilder();
|
||||
foreach (var part in parts)
|
||||
{
|
||||
sb.Append(char.ToUpperInvariant(part[0]));
|
||||
sb.Append(part[1..].ToLowerInvariant());
|
||||
}
|
||||
|
||||
text = sb.ToString();
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
public string[] Labels => this.labels;
|
||||
|
||||
public int Min => this.min;
|
||||
|
||||
public int Max => this.max;
|
||||
|
||||
public ProcessStepValue this[T step] => this.stepsData[step];
|
||||
}
|
||||
@@ -0,0 +1,258 @@
|
||||
using System.Globalization;
|
||||
using System.Numerics;
|
||||
|
||||
namespace AIStudio.Tools;
|
||||
|
||||
public readonly record struct ProcessStepValue(int Step, string Name) : INumber<ProcessStepValue>
|
||||
{
|
||||
public static implicit operator int(ProcessStepValue process) => process.Step;
|
||||
|
||||
#region INumber implementation
|
||||
|
||||
#region Implementation of IComparable
|
||||
|
||||
public int CompareTo(object? obj) => this.Step.CompareTo(obj);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation of IComparable<in ProcessStepValue>
|
||||
|
||||
public int CompareTo(ProcessStepValue other) => this.Step.CompareTo(other.Step);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation of IFormattable
|
||||
|
||||
public string ToString(string? format, IFormatProvider? formatProvider) => this.Step.ToString(format, formatProvider);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation of IParsable<ProcessStepValue>
|
||||
|
||||
public static ProcessStepValue Parse(string s, IFormatProvider? provider) => new(int.Parse(s, provider), string.Empty);
|
||||
|
||||
public static bool TryParse(string? s, IFormatProvider? provider, out ProcessStepValue result)
|
||||
{
|
||||
if (int.TryParse(s, provider, out var stepValue))
|
||||
{
|
||||
result = new ProcessStepValue(stepValue, string.Empty);
|
||||
return true;
|
||||
}
|
||||
|
||||
result = default;
|
||||
return false;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Implementation of ISpanFormattable
|
||||
|
||||
public bool TryFormat(Span<char> destination, out int charsWritten, ReadOnlySpan<char> format, IFormatProvider? provider) => this.Step.TryFormat(destination, out charsWritten, format, provider);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation of ISpanParsable<ProcessStepValue>
|
||||
|
||||
public static ProcessStepValue Parse(ReadOnlySpan<char> s, IFormatProvider? provider) => new(int.Parse(s, provider), string.Empty);
|
||||
|
||||
public static bool TryParse(ReadOnlySpan<char> s, IFormatProvider? provider, out ProcessStepValue result)
|
||||
{
|
||||
if (int.TryParse(s, provider, out int stepValue))
|
||||
{
|
||||
result = new ProcessStepValue(stepValue, string.Empty);
|
||||
return true;
|
||||
}
|
||||
|
||||
result = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation of IAdditionOperators<ProcessStepValue,ProcessStepValue,ProcessStepValue>
|
||||
|
||||
public static ProcessStepValue operator +(ProcessStepValue left, ProcessStepValue right) => left with { Step = left.Step + right.Step };
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation of IAdditiveIdentity<ProcessStepValue,ProcessStepValue>
|
||||
|
||||
public static ProcessStepValue AdditiveIdentity => new(0, string.Empty);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation of IComparisonOperators<ProcessStepValue,ProcessStepValue,bool>
|
||||
|
||||
public static bool operator >(ProcessStepValue left, ProcessStepValue right) => left.Step > right.Step;
|
||||
|
||||
public static bool operator >=(ProcessStepValue left, ProcessStepValue right) => left.Step >= right.Step;
|
||||
|
||||
public static bool operator <(ProcessStepValue left, ProcessStepValue right) => left.Step < right.Step;
|
||||
|
||||
public static bool operator <=(ProcessStepValue left, ProcessStepValue right) => left.Step <= right.Step;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation of IDecrementOperators<ProcessStepValue>
|
||||
|
||||
public static ProcessStepValue operator --(ProcessStepValue value) => value with { Step = value.Step - 1 };
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation of IDivisionOperators<ProcessStepValue,ProcessStepValue,ProcessStepValue>
|
||||
|
||||
public static ProcessStepValue operator /(ProcessStepValue left, ProcessStepValue right) => left with { Step = left.Step / right.Step };
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation of IIncrementOperators<ProcessStepValue>
|
||||
|
||||
public static ProcessStepValue operator ++(ProcessStepValue value) => value with { Step = value.Step + 1 };
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation of IModulusOperators<ProcessStepValue,ProcessStepValue,ProcessStepValue>
|
||||
|
||||
public static ProcessStepValue operator %(ProcessStepValue left, ProcessStepValue right) => left with { Step = left.Step % right.Step };
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation of IMultiplicativeIdentity<ProcessStepValue,ProcessStepValue>
|
||||
|
||||
public static ProcessStepValue MultiplicativeIdentity => new(1, string.Empty);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation of IMultiplyOperators<ProcessStepValue,ProcessStepValue,ProcessStepValue>
|
||||
|
||||
public static ProcessStepValue operator *(ProcessStepValue left, ProcessStepValue right) => left with { Step = left.Step * right.Step };
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation of ISubtractionOperators<ProcessStepValue,ProcessStepValue,ProcessStepValue>
|
||||
|
||||
public static ProcessStepValue operator -(ProcessStepValue left, ProcessStepValue right) => left with { Step = left.Step - right.Step };
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation of IUnaryNegationOperators<ProcessStepValue,ProcessStepValue>
|
||||
|
||||
public static ProcessStepValue operator -(ProcessStepValue value) => value with { Step = -value.Step };
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation of IUnaryPlusOperators<ProcessStepValue,ProcessStepValue>
|
||||
|
||||
public static ProcessStepValue operator +(ProcessStepValue value) => value;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation of INumberBase<ProcessStepValue>
|
||||
|
||||
public static ProcessStepValue Abs(ProcessStepValue value) => value with { Step = Math.Abs(value.Step) };
|
||||
|
||||
public static bool IsCanonical(ProcessStepValue value) => true;
|
||||
public static bool IsComplexNumber(ProcessStepValue value) => false;
|
||||
public static bool IsEvenInteger(ProcessStepValue value) => value.Step % 2 == 0;
|
||||
public static bool IsFinite(ProcessStepValue value) => true;
|
||||
public static bool IsImaginaryNumber(ProcessStepValue value) => false;
|
||||
public static bool IsInfinity(ProcessStepValue value) => false;
|
||||
public static bool IsInteger(ProcessStepValue value) => true;
|
||||
public static bool IsNaN(ProcessStepValue value) => false;
|
||||
public static bool IsNegative(ProcessStepValue value) => value.Step < 0;
|
||||
public static bool IsNegativeInfinity(ProcessStepValue value) => false;
|
||||
public static bool IsNormal(ProcessStepValue value) => true;
|
||||
public static bool IsOddInteger(ProcessStepValue value) => value.Step % 2 != 0;
|
||||
public static bool IsPositive(ProcessStepValue value) => value.Step > 0;
|
||||
public static bool IsPositiveInfinity(ProcessStepValue value) => false;
|
||||
public static bool IsRealNumber(ProcessStepValue value) => true;
|
||||
public static bool IsSubnormal(ProcessStepValue value) => false;
|
||||
public static bool IsZero(ProcessStepValue value) => value.Step == 0;
|
||||
public static ProcessStepValue MaxMagnitude(ProcessStepValue x, ProcessStepValue y)
|
||||
{
|
||||
return x with { Step = Math.Max(Math.Abs(x.Step), Math.Abs(y.Step)) };
|
||||
}
|
||||
|
||||
public static ProcessStepValue MaxMagnitudeNumber(ProcessStepValue x, ProcessStepValue y) => MaxMagnitude(x, y);
|
||||
|
||||
public static ProcessStepValue MinMagnitude(ProcessStepValue x, ProcessStepValue y) => x with { Step = Math.Min(Math.Abs(x.Step), Math.Abs(y.Step)) };
|
||||
|
||||
public static ProcessStepValue MinMagnitudeNumber(ProcessStepValue x, ProcessStepValue y) => MinMagnitude(x, y);
|
||||
|
||||
public static ProcessStepValue Parse(ReadOnlySpan<char> s, NumberStyles style, IFormatProvider? provider) => new(int.Parse(s, style, provider), string.Empty);
|
||||
|
||||
public static ProcessStepValue Parse(string s, NumberStyles style, IFormatProvider? provider) => new(int.Parse(s, style, provider), string.Empty);
|
||||
|
||||
public static bool TryConvertFromChecked<TOther>(TOther value, out ProcessStepValue result) where TOther : INumberBase<TOther>
|
||||
{
|
||||
if (TOther.TryConvertToChecked(value, out int intValue))
|
||||
{
|
||||
result = new ProcessStepValue(intValue, string.Empty);
|
||||
return true;
|
||||
}
|
||||
|
||||
result = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool TryConvertFromSaturating<TOther>(TOther value, out ProcessStepValue result) where TOther : INumberBase<TOther>
|
||||
{
|
||||
if (TOther.TryConvertToSaturating(value, out int intValue))
|
||||
{
|
||||
result = new ProcessStepValue(intValue, string.Empty);
|
||||
return true;
|
||||
}
|
||||
result = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool TryConvertFromTruncating<TOther>(TOther value, out ProcessStepValue result) where TOther : INumberBase<TOther>
|
||||
{
|
||||
if (TOther.TryConvertToTruncating(value, out int intValue))
|
||||
{
|
||||
result = new ProcessStepValue(intValue, string.Empty);
|
||||
return true;
|
||||
}
|
||||
result = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool TryConvertToChecked<TOther>(ProcessStepValue value, out TOther result) where TOther : INumberBase<TOther> => TOther.TryConvertFromChecked(value.Step, out result!);
|
||||
|
||||
public static bool TryConvertToSaturating<TOther>(ProcessStepValue value, out TOther result) where TOther : INumberBase<TOther> => TOther.TryConvertFromSaturating(value.Step, out result!);
|
||||
|
||||
public static bool TryConvertToTruncating<TOther>(ProcessStepValue value, out TOther result) where TOther : INumberBase<TOther> => TOther.TryConvertFromTruncating(value.Step, out result!);
|
||||
|
||||
public static bool TryParse(ReadOnlySpan<char> s, NumberStyles style, IFormatProvider? provider, out ProcessStepValue result)
|
||||
{
|
||||
if (int.TryParse(s, style, provider, out var stepValue))
|
||||
{
|
||||
result = new ProcessStepValue(stepValue, string.Empty);
|
||||
return true;
|
||||
}
|
||||
|
||||
result = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool TryParse(string? s, NumberStyles style, IFormatProvider? provider, out ProcessStepValue result)
|
||||
{
|
||||
if (int.TryParse(s, style, provider, out var stepValue))
|
||||
{
|
||||
result = new ProcessStepValue(stepValue, string.Empty);
|
||||
return true;
|
||||
}
|
||||
|
||||
result = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static ProcessStepValue One => new(1, string.Empty);
|
||||
|
||||
public static int Radix => 2;
|
||||
|
||||
public static ProcessStepValue Zero => new(0, string.Empty);
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
namespace AIStudio.Tools;
|
||||
|
||||
/// <inheritdoc />
|
||||
public sealed class ThreadSafeRandom : Random
|
||||
{
|
||||
private static readonly object LOCK = new();
|
||||
|
||||
#region Overrides of Random
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int Next()
|
||||
{
|
||||
lock (LOCK)
|
||||
return base.Next();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int Next(int maxValue)
|
||||
{
|
||||
lock (LOCK)
|
||||
return base.Next(maxValue);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int Next(int minValue, int maxValue)
|
||||
{
|
||||
lock (LOCK)
|
||||
return base.Next(minValue, maxValue);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void NextBytes(byte[] buffer)
|
||||
{
|
||||
lock (LOCK)
|
||||
base.NextBytes(buffer);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void NextBytes(Span<byte> buffer)
|
||||
{
|
||||
lock (LOCK)
|
||||
base.NextBytes(buffer);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override double NextDouble()
|
||||
{
|
||||
lock (LOCK)
|
||||
return base.NextDouble();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override long NextInt64()
|
||||
{
|
||||
lock (LOCK)
|
||||
return base.NextInt64();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override long NextInt64(long maxValue)
|
||||
{
|
||||
lock (LOCK)
|
||||
return base.NextInt64(maxValue);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override long NextInt64(long minValue, long maxValue)
|
||||
{
|
||||
lock (LOCK)
|
||||
return base.NextInt64(minValue, maxValue);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override float NextSingle()
|
||||
{
|
||||
lock (LOCK)
|
||||
return base.NextSingle();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override double Sample()
|
||||
{
|
||||
lock (LOCK)
|
||||
return base.Sample();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
Reference in new issue
Block a user