From c8d918408ff0060ad1a957efca52f80018927eba Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Thu, 1 Aug 2024 14:35:32 +0200 Subject: [PATCH] Implemented utilities to visualize agent processes --- app/MindWork AI Studio/Tools/Process.cs | 67 +++++ .../Tools/ProcessStepValue.cs | 258 ++++++++++++++++++ 2 files changed, 325 insertions(+) create mode 100644 app/MindWork AI Studio/Tools/Process.cs create mode 100644 app/MindWork AI Studio/Tools/ProcessStepValue.cs diff --git a/app/MindWork AI Studio/Tools/Process.cs b/app/MindWork AI Studio/Tools/Process.cs new file mode 100644 index 00000000..53488915 --- /dev/null +++ b/app/MindWork AI Studio/Tools/Process.cs @@ -0,0 +1,67 @@ +using System.Text; + +namespace AIStudio.Tools; + +public sealed class Process where T : struct, Enum +{ + public static readonly Process INSTANCE = new(); + + private readonly Dictionary stepsData = []; + private readonly int min = int.MaxValue; + private readonly int max = int.MinValue; + private readonly string[] labels; + + private Process() + { + var values = Enum.GetValues(); + 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]; +} \ No newline at end of file diff --git a/app/MindWork AI Studio/Tools/ProcessStepValue.cs b/app/MindWork AI Studio/Tools/ProcessStepValue.cs new file mode 100644 index 00000000..b75b5e0c --- /dev/null +++ b/app/MindWork AI Studio/Tools/ProcessStepValue.cs @@ -0,0 +1,258 @@ +using System.Globalization; +using System.Numerics; + +namespace AIStudio.Tools; + +public readonly record struct ProcessStepValue(int Step, string Name) : INumber +{ + 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 + + 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 + + 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 destination, out int charsWritten, ReadOnlySpan format, IFormatProvider? provider) => this.Step.TryFormat(destination, out charsWritten, format, provider); + + #endregion + + #region Implementation of ISpanParsable + + public static ProcessStepValue Parse(ReadOnlySpan s, IFormatProvider? provider) => new(int.Parse(s, provider), string.Empty); + + public static bool TryParse(ReadOnlySpan 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 + + public static ProcessStepValue operator +(ProcessStepValue left, ProcessStepValue right) => left with { Step = left.Step + right.Step }; + + #endregion + + #region Implementation of IAdditiveIdentity + + public static ProcessStepValue AdditiveIdentity => new(0, string.Empty); + + #endregion + + #region Implementation of IComparisonOperators + + 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 + + public static ProcessStepValue operator --(ProcessStepValue value) => value with { Step = value.Step - 1 }; + + #endregion + + #region Implementation of IDivisionOperators + + public static ProcessStepValue operator /(ProcessStepValue left, ProcessStepValue right) => left with { Step = left.Step / right.Step }; + + #endregion + + #region Implementation of IIncrementOperators + + public static ProcessStepValue operator ++(ProcessStepValue value) => value with { Step = value.Step + 1 }; + + #endregion + + #region Implementation of IModulusOperators + + public static ProcessStepValue operator %(ProcessStepValue left, ProcessStepValue right) => left with { Step = left.Step % right.Step }; + + #endregion + + #region Implementation of IMultiplicativeIdentity + + public static ProcessStepValue MultiplicativeIdentity => new(1, string.Empty); + + #endregion + + #region Implementation of IMultiplyOperators + + public static ProcessStepValue operator *(ProcessStepValue left, ProcessStepValue right) => left with { Step = left.Step * right.Step }; + + #endregion + + #region Implementation of ISubtractionOperators + + public static ProcessStepValue operator -(ProcessStepValue left, ProcessStepValue right) => left with { Step = left.Step - right.Step }; + + #endregion + + #region Implementation of IUnaryNegationOperators + + public static ProcessStepValue operator -(ProcessStepValue value) => value with { Step = -value.Step }; + + #endregion + + #region Implementation of IUnaryPlusOperators + + public static ProcessStepValue operator +(ProcessStepValue value) => value; + + #endregion + + #region Implementation of INumberBase + + 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 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 value, out ProcessStepValue result) where TOther : INumberBase + { + if (TOther.TryConvertToChecked(value, out int intValue)) + { + result = new ProcessStepValue(intValue, string.Empty); + return true; + } + + result = default; + return false; + } + + public static bool TryConvertFromSaturating(TOther value, out ProcessStepValue result) where TOther : INumberBase + { + if (TOther.TryConvertToSaturating(value, out int intValue)) + { + result = new ProcessStepValue(intValue, string.Empty); + return true; + } + result = default; + return false; + } + + public static bool TryConvertFromTruncating(TOther value, out ProcessStepValue result) where TOther : INumberBase + { + if (TOther.TryConvertToTruncating(value, out int intValue)) + { + result = new ProcessStepValue(intValue, string.Empty); + return true; + } + result = default; + return false; + } + + public static bool TryConvertToChecked(ProcessStepValue value, out TOther result) where TOther : INumberBase => TOther.TryConvertFromChecked(value.Step, out result!); + + public static bool TryConvertToSaturating(ProcessStepValue value, out TOther result) where TOther : INumberBase => TOther.TryConvertFromSaturating(value.Step, out result!); + + public static bool TryConvertToTruncating(ProcessStepValue value, out TOther result) where TOther : INumberBase => TOther.TryConvertFromTruncating(value.Step, out result!); + + public static bool TryParse(ReadOnlySpan 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 +} \ No newline at end of file