Files
nexus/backend/Services/OpenClawInvocationContextFactory.cs
T
AzuTear f5552218bc
CI - Build & Test / Backend (.NET) (push) Successful in 42s
CI - Build & Test / Frontend (Vue/TS) (push) Successful in 2m46s
CI - Build & Test / Security Check (push) Successful in 3s
CI - Build & Test / Deploy Nexus (push) Successful in 56s
feat: ship agent-first mission control v0.2.57
2026-07-31 22:39:47 +02:00

81 lines
2.8 KiB
C#

using System.Diagnostics;
using System.Security.Cryptography;
using System.Text;
namespace Nexus.Api.Services;
public static class OpenClawInvocationContextFactory
{
private const int MaxMetadataLength = 128;
public static OpenClawInvocationContext Create(
string? actor = null,
string? idempotencyKey = null,
string? correlationId = null,
string? traceParent = null,
bool includeIdempotencyParameter = false)
{
var normalizedIdempotencyKey = NormalizeOrGenerate(idempotencyKey, "idem");
var normalizedCorrelationId = NormalizeOrGenerate(correlationId, "corr");
var normalizedActor = NormalizeActor(actor);
var normalizedTraceParent = NormalizeTraceParent(traceParent);
return new OpenClawInvocationContext(
normalizedIdempotencyKey,
normalizedCorrelationId,
normalizedActor,
normalizedTraceParent,
includeIdempotencyParameter);
}
public static string Hash(string value)
=> Convert.ToHexStringLower(SHA256.HashData(Encoding.UTF8.GetBytes(value)));
private static string NormalizeOrGenerate(string? value, string prefix)
{
var trimmed = value?.Trim();
if (string.IsNullOrWhiteSpace(trimmed))
return $"{prefix}_{Guid.NewGuid():N}";
if (trimmed.Length > MaxMetadataLength)
throw new ArgumentException($"{prefix} metadata must not exceed {MaxMetadataLength} characters.");
if (trimmed.Any(char.IsControl))
throw new ArgumentException($"{prefix} metadata must not contain control characters.");
return trimmed;
}
private static string NormalizeActor(string? actor)
{
var trimmed = actor?.Trim();
if (string.IsNullOrWhiteSpace(trimmed))
return "nexus-system";
if (trimmed.Length > MaxMetadataLength)
return $"sha256:{Hash(trimmed)}";
return trimmed.Any(char.IsControl)
? $"sha256:{Hash(trimmed)}"
: trimmed;
}
private static string NormalizeTraceParent(string? traceParent)
{
var candidate = traceParent?.Trim();
if (!string.IsNullOrWhiteSpace(candidate))
{
if (!OpenClawGatewayProtocol.IsValidTraceParent(candidate))
throw new ArgumentException("traceparent must be a valid W3C trace context.", nameof(traceParent));
return candidate;
}
if (Activity.Current?.Id is { } current &&
OpenClawGatewayProtocol.IsValidTraceParent(current))
{
return current;
}
using var activity = new Activity("Nexus.OpenClaw.Invocation")
.SetIdFormat(ActivityIdFormat.W3C);
activity.Start();
return activity.Id
?? throw new InvalidOperationException("Could not create a W3C traceparent.");
}
}