feat: ship agent-first mission control v0.2.57
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
using System.Diagnostics;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Nexus.Api.Models;
|
||||
|
||||
namespace Nexus.Api.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Builds the transport-safe result metadata shared by browser, bridge and
|
||||
/// OpenClaw mutation responses. URLs deliberately remain a frontend concern.
|
||||
/// </summary>
|
||||
public static class OperationResultFactory
|
||||
{
|
||||
private const int MaxOperationIdLength = 128;
|
||||
|
||||
public static OperationResultDto FromHttpContext(
|
||||
HttpContext context,
|
||||
string status,
|
||||
EntityRefDto? primaryRef,
|
||||
int revision = 0,
|
||||
IEnumerable<EntityRefDto>? affectedRefs = null)
|
||||
{
|
||||
var requestedCorrelation = context.Request.Headers["X-Correlation-ID"]
|
||||
.FirstOrDefault();
|
||||
var operationId = IsSafeIdentifier(requestedCorrelation)
|
||||
? requestedCorrelation!.Trim()
|
||||
: IsSafeIdentifier(context.TraceIdentifier)
|
||||
? context.TraceIdentifier.Trim()
|
||||
: Guid.NewGuid().ToString("N");
|
||||
var traceId = Activity.Current?.Id;
|
||||
if (string.IsNullOrWhiteSpace(traceId))
|
||||
{
|
||||
var traceParent = context.Request.Headers["traceparent"].FirstOrDefault();
|
||||
traceId = IsSafeIdentifier(traceParent) ? traceParent!.Trim() : null;
|
||||
}
|
||||
|
||||
context.Response.Headers["X-Correlation-ID"] = operationId;
|
||||
return Create(
|
||||
operationId,
|
||||
status,
|
||||
revision,
|
||||
primaryRef,
|
||||
affectedRefs,
|
||||
traceId);
|
||||
}
|
||||
|
||||
public static OperationResultDto FromInvocation(
|
||||
OpenClawInvocationContext context,
|
||||
string status,
|
||||
EntityRefDto? primaryRef,
|
||||
int revision = 0,
|
||||
IEnumerable<EntityRefDto>? affectedRefs = null)
|
||||
=> Create(
|
||||
context.CorrelationId,
|
||||
status,
|
||||
revision,
|
||||
primaryRef,
|
||||
affectedRefs,
|
||||
Activity.Current?.Id ?? context.TraceParent);
|
||||
|
||||
public static OperationResultDto Create(
|
||||
string operationId,
|
||||
string status,
|
||||
int revision,
|
||||
EntityRefDto? primaryRef,
|
||||
IEnumerable<EntityRefDto>? affectedRefs = null,
|
||||
string? traceId = null)
|
||||
{
|
||||
var uniqueAffected = (affectedRefs ?? [])
|
||||
.Where(reference =>
|
||||
primaryRef is null ||
|
||||
!string.Equals(reference.Type, primaryRef.Type, StringComparison.Ordinal) ||
|
||||
!string.Equals(reference.Id, primaryRef.Id, StringComparison.Ordinal))
|
||||
.DistinctBy(reference => (reference.Type, reference.Id))
|
||||
.ToArray();
|
||||
|
||||
return new OperationResultDto(
|
||||
operationId,
|
||||
status,
|
||||
Math.Max(0, revision),
|
||||
primaryRef,
|
||||
uniqueAffected,
|
||||
traceId);
|
||||
}
|
||||
|
||||
private static bool IsSafeIdentifier(string? value)
|
||||
=> !string.IsNullOrWhiteSpace(value)
|
||||
&& value.Length <= MaxOperationIdLength
|
||||
&& !value.Any(char.IsControl);
|
||||
}
|
||||
Reference in New Issue
Block a user