feat: ship agent-first mission control v0.2.57
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
namespace Nexus.Api.Data;
|
||||
|
||||
/// <summary>
|
||||
/// Durable, secret-free proposal for creating one OpenClaw-owned agent.
|
||||
/// Nexus owns the approval workflow only; the resulting agent remains owned by
|
||||
/// OpenClaw.
|
||||
/// </summary>
|
||||
public sealed class AgentProposal
|
||||
{
|
||||
public Guid Id { get; init; } = Guid.NewGuid();
|
||||
public required string Source { get; set; }
|
||||
public required string RequestedName { get; set; }
|
||||
public required string RequestedAgentId { get; set; }
|
||||
public string? Role { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public string? Model { get; set; }
|
||||
public string? Emoji { get; set; }
|
||||
public string? Avatar { get; set; }
|
||||
public required string Workspace { get; set; }
|
||||
public required string StandardFilesJson { get; set; }
|
||||
public required string StandardFilesHash { get; set; }
|
||||
public string Status { get; set; } = AgentProposalStates.AwaitingApproval;
|
||||
public required string RequestedBy { get; set; }
|
||||
public string? ApprovedBy { get; set; }
|
||||
public string? RejectedBy { get; set; }
|
||||
public string? RejectionReason { get; set; }
|
||||
public string? OpenClawAgentId { get; set; }
|
||||
public string? OpenClawWorkspace { get; set; }
|
||||
public string? LastErrorCode { get; set; }
|
||||
public string? LastErrorMessage { get; set; }
|
||||
public int Revision { get; set; } = 1;
|
||||
public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
|
||||
public DateTimeOffset UpdatedAt { get; set; } = DateTimeOffset.UtcNow;
|
||||
public DateTimeOffset? ApprovedAt { get; set; }
|
||||
public DateTimeOffset? RejectedAt { get; set; }
|
||||
public DateTimeOffset? CompletedAt { get; set; }
|
||||
public ICollection<AgentProvisionRequest> ProvisionRequests { get; set; } =
|
||||
new List<AgentProvisionRequest>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// One explicitly authorized provisioning attempt. A request that reached the
|
||||
/// dispatch boundary is never silently re-queued after a restart.
|
||||
/// </summary>
|
||||
public sealed class AgentProvisionRequest
|
||||
{
|
||||
public Guid Id { get; init; } = Guid.NewGuid();
|
||||
public Guid ProposalId { get; set; }
|
||||
public AgentProposal Proposal { get; set; } = null!;
|
||||
public int Attempt { get; set; }
|
||||
public required string Stage { get; set; }
|
||||
public string Status { get; set; } = AgentProvisionRequestStates.Queued;
|
||||
public required string IdempotencyKeyHash { get; set; }
|
||||
public required string Actor { get; set; }
|
||||
public required string CorrelationId { get; set; }
|
||||
public string? TraceParent { get; set; }
|
||||
public string? OpenClawAgentId { get; set; }
|
||||
public string? LastErrorCode { get; set; }
|
||||
public string? LastErrorMessage { get; set; }
|
||||
public string? LeaseOwner { get; set; }
|
||||
public DateTimeOffset? LeaseUntil { get; set; }
|
||||
public int Revision { get; set; } = 1;
|
||||
public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
|
||||
public DateTimeOffset UpdatedAt { get; set; } = DateTimeOffset.UtcNow;
|
||||
public DateTimeOffset? DispatchStartedAt { get; set; }
|
||||
public DateTimeOffset? CompletedAt { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Hash-only idempotency claim. Raw idempotency keys and request content are
|
||||
/// deliberately not persisted.
|
||||
/// </summary>
|
||||
public sealed class OperationClaim
|
||||
{
|
||||
public Guid Id { get; init; } = Guid.NewGuid();
|
||||
public required string Operation { get; set; }
|
||||
public required string IdempotencyKeyHash { get; set; }
|
||||
public required string RequestHash { get; set; }
|
||||
public Guid? ResourceId { get; set; }
|
||||
public required string State { get; set; }
|
||||
public string? ResultCode { get; set; }
|
||||
public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
|
||||
public DateTimeOffset? CompletedAt { get; set; }
|
||||
public DateTimeOffset ExpiresAt { get; set; } =
|
||||
DateTimeOffset.UtcNow.AddDays(7);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transactional, content-minimized domain event. The payload may contain
|
||||
/// identifiers and states, but never proposal markdown or credentials.
|
||||
/// </summary>
|
||||
public sealed class OutboxEvent
|
||||
{
|
||||
public long Sequence { get; init; }
|
||||
public Guid EventId { get; init; } = Guid.NewGuid();
|
||||
public required string Type { get; set; }
|
||||
public required string AggregateType { get; set; }
|
||||
public required string AggregateId { get; set; }
|
||||
public int AggregateRevision { get; set; }
|
||||
public required string PayloadJson { get; set; }
|
||||
public DateTimeOffset OccurredAt { get; set; } = DateTimeOffset.UtcNow;
|
||||
public DateTimeOffset? PublishedAt { get; set; }
|
||||
public int PublishAttempts { get; set; }
|
||||
public string? LastErrorCode { get; set; }
|
||||
}
|
||||
|
||||
public static class AgentProposalStates
|
||||
{
|
||||
public const string Draft = "draft";
|
||||
public const string AwaitingApproval = "awaiting_approval";
|
||||
public const string Provisioning = "provisioning";
|
||||
public const string Ready = "ready";
|
||||
public const string Partial = "partial";
|
||||
public const string Failed = "failed";
|
||||
public const string InDoubt = "in_doubt";
|
||||
public const string Rejected = "rejected";
|
||||
}
|
||||
|
||||
public static class AgentProvisionStages
|
||||
{
|
||||
public const string CreateAgent = "create_agent";
|
||||
public const string ReconcileAgent = "reconcile_agent";
|
||||
public const string FinalizeFiles = "finalize_files";
|
||||
}
|
||||
|
||||
public static class AgentProvisionRequestStates
|
||||
{
|
||||
public const string Queued = "queued";
|
||||
public const string Dispatching = "dispatching";
|
||||
public const string Completed = "completed";
|
||||
public const string Failed = "failed";
|
||||
public const string Partial = "partial";
|
||||
public const string InDoubt = "in_doubt";
|
||||
public const string Blocked = "blocked";
|
||||
}
|
||||
Reference in New Issue
Block a user