feat: ship agent-first mission control v0.2.57
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
|
||||
namespace Nexus.Api.Repositories;
|
||||
|
||||
internal readonly record struct OpenClawRunCursorPosition(
|
||||
DateTimeOffset CreatedAt,
|
||||
Guid? Id);
|
||||
|
||||
internal static class OpenClawRunCursorCodec
|
||||
{
|
||||
private const string Version = "v1";
|
||||
private const int MaximumEncodedLength = 128;
|
||||
|
||||
public static string Encode(DateTimeOffset createdAt, Guid id)
|
||||
{
|
||||
var payload = string.Create(
|
||||
CultureInfo.InvariantCulture,
|
||||
$"{Version}|{createdAt.UtcTicks}|{id:N}");
|
||||
|
||||
return Convert.ToBase64String(Encoding.UTF8.GetBytes(payload))
|
||||
.TrimEnd('=')
|
||||
.Replace('+', '-')
|
||||
.Replace('/', '_');
|
||||
}
|
||||
|
||||
public static bool TryDecode(
|
||||
string? cursor,
|
||||
out OpenClawRunCursorPosition position)
|
||||
{
|
||||
position = default;
|
||||
if (string.IsNullOrWhiteSpace(cursor) || cursor.Length > MaximumEncodedLength)
|
||||
return false;
|
||||
|
||||
// Compatibility with the original run cursor, which was an unversioned
|
||||
// UTC tick value and therefore cannot express the Id tie-breaker.
|
||||
if (long.TryParse(
|
||||
cursor,
|
||||
NumberStyles.None,
|
||||
CultureInfo.InvariantCulture,
|
||||
out var legacyTicks))
|
||||
{
|
||||
return TryCreatePosition(legacyTicks, null, out position);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var normalized = cursor
|
||||
.Replace('-', '+')
|
||||
.Replace('_', '/');
|
||||
|
||||
normalized = (normalized.Length % 4) switch
|
||||
{
|
||||
0 => normalized,
|
||||
2 => normalized + "==",
|
||||
3 => normalized + "=",
|
||||
_ => throw new FormatException("Invalid Base64Url length.")
|
||||
};
|
||||
|
||||
var payload = new UTF8Encoding(
|
||||
encoderShouldEmitUTF8Identifier: false,
|
||||
throwOnInvalidBytes: true)
|
||||
.GetString(Convert.FromBase64String(normalized));
|
||||
var parts = payload.Split('|');
|
||||
if (parts.Length != 3
|
||||
|| !string.Equals(parts[0], Version, StringComparison.Ordinal)
|
||||
|| !long.TryParse(
|
||||
parts[1],
|
||||
NumberStyles.None,
|
||||
CultureInfo.InvariantCulture,
|
||||
out var utcTicks)
|
||||
|| !Guid.TryParseExact(parts[2], "N", out var id))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return TryCreatePosition(utcTicks, id, out position);
|
||||
}
|
||||
catch (Exception exception) when (
|
||||
exception is FormatException
|
||||
or DecoderFallbackException)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool TryCreatePosition(
|
||||
long utcTicks,
|
||||
Guid? id,
|
||||
out OpenClawRunCursorPosition position)
|
||||
{
|
||||
position = default;
|
||||
try
|
||||
{
|
||||
position = new OpenClawRunCursorPosition(
|
||||
new DateTimeOffset(utcTicks, TimeSpan.Zero),
|
||||
id);
|
||||
return true;
|
||||
}
|
||||
catch (ArgumentOutOfRangeException)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user