550 lines
14 KiB
C#
550 lines
14 KiB
C#
// Copyright (c) StellaOps. All rights reserved.
|
|
// Licensed under the BUSL-1.1 license.
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text.Json.Serialization;
|
|
|
|
namespace StellaOps.Cli.Services.Models.Chat;
|
|
|
|
/// <summary>
|
|
/// Output format for chat commands.
|
|
/// </summary>
|
|
internal enum ChatOutputFormat
|
|
{
|
|
Table,
|
|
Json,
|
|
Markdown
|
|
}
|
|
|
|
/// <summary>
|
|
/// Chat query request sent to the AdvisoryAI chat API.
|
|
/// </summary>
|
|
internal sealed record ChatQueryRequest
|
|
{
|
|
[JsonPropertyName("query")]
|
|
public required string Query { get; init; }
|
|
|
|
[JsonPropertyName("artifactDigest")]
|
|
public string? ArtifactDigest { get; init; }
|
|
|
|
[JsonPropertyName("imageReference")]
|
|
public string? ImageReference { get; init; }
|
|
|
|
[JsonPropertyName("environment")]
|
|
public string? Environment { get; init; }
|
|
|
|
[JsonPropertyName("conversationId")]
|
|
public string? ConversationId { get; init; }
|
|
|
|
[JsonPropertyName("userRoles")]
|
|
public List<string>? UserRoles { get; init; }
|
|
|
|
[JsonPropertyName("noAction")]
|
|
public bool NoAction { get; init; } = true;
|
|
|
|
[JsonPropertyName("includeEvidence")]
|
|
public bool IncludeEvidence { get; init; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Chat query response from the AdvisoryAI chat API.
|
|
/// </summary>
|
|
internal sealed record ChatQueryResponse
|
|
{
|
|
[JsonPropertyName("responseId")]
|
|
public required string ResponseId { get; init; }
|
|
|
|
[JsonPropertyName("bundleId")]
|
|
public string? BundleId { get; init; }
|
|
|
|
[JsonPropertyName("intent")]
|
|
public required string Intent { get; init; }
|
|
|
|
[JsonPropertyName("generatedAt")]
|
|
public required DateTimeOffset GeneratedAt { get; init; }
|
|
|
|
[JsonPropertyName("summary")]
|
|
public required string Summary { get; init; }
|
|
|
|
[JsonPropertyName("impact")]
|
|
public ChatImpactAssessment? Impact { get; init; }
|
|
|
|
[JsonPropertyName("reachability")]
|
|
public ChatReachabilityAssessment? Reachability { get; init; }
|
|
|
|
[JsonPropertyName("mitigations")]
|
|
public List<ChatMitigationOption> Mitigations { get; init; } = [];
|
|
|
|
[JsonPropertyName("evidenceLinks")]
|
|
public List<ChatEvidenceLink> EvidenceLinks { get; init; } = [];
|
|
|
|
[JsonPropertyName("confidence")]
|
|
public required ChatConfidence Confidence { get; init; }
|
|
|
|
[JsonPropertyName("proposedActions")]
|
|
public List<ChatProposedAction> ProposedActions { get; init; } = [];
|
|
|
|
[JsonPropertyName("followUp")]
|
|
public ChatFollowUp? FollowUp { get; init; }
|
|
|
|
[JsonPropertyName("diagnostics")]
|
|
public ChatDiagnostics? Diagnostics { get; init; }
|
|
}
|
|
|
|
internal sealed record ChatImpactAssessment
|
|
{
|
|
[JsonPropertyName("severity")]
|
|
public string? Severity { get; init; }
|
|
|
|
[JsonPropertyName("affectedComponents")]
|
|
public List<string> AffectedComponents { get; init; } = [];
|
|
|
|
[JsonPropertyName("description")]
|
|
public string? Description { get; init; }
|
|
}
|
|
|
|
internal sealed record ChatReachabilityAssessment
|
|
{
|
|
[JsonPropertyName("reachable")]
|
|
public bool Reachable { get; init; }
|
|
|
|
[JsonPropertyName("paths")]
|
|
public List<string> Paths { get; init; } = [];
|
|
|
|
[JsonPropertyName("confidence")]
|
|
public double Confidence { get; init; }
|
|
}
|
|
|
|
internal sealed record ChatMitigationOption
|
|
{
|
|
[JsonPropertyName("id")]
|
|
public required string Id { get; init; }
|
|
|
|
[JsonPropertyName("title")]
|
|
public required string Title { get; init; }
|
|
|
|
[JsonPropertyName("description")]
|
|
public string? Description { get; init; }
|
|
|
|
[JsonPropertyName("effort")]
|
|
public string? Effort { get; init; }
|
|
|
|
[JsonPropertyName("recommended")]
|
|
public bool Recommended { get; init; }
|
|
}
|
|
|
|
internal sealed record ChatEvidenceLink
|
|
{
|
|
[JsonPropertyName("type")]
|
|
public required string Type { get; init; }
|
|
|
|
[JsonPropertyName("ref")]
|
|
public required string Ref { get; init; }
|
|
|
|
[JsonPropertyName("label")]
|
|
public string? Label { get; init; }
|
|
|
|
[JsonPropertyName("digest")]
|
|
public string? Digest { get; init; }
|
|
}
|
|
|
|
internal sealed record ChatConfidence
|
|
{
|
|
[JsonPropertyName("overall")]
|
|
public double Overall { get; init; }
|
|
|
|
[JsonPropertyName("evidenceQuality")]
|
|
public double EvidenceQuality { get; init; }
|
|
|
|
[JsonPropertyName("modelCertainty")]
|
|
public double ModelCertainty { get; init; }
|
|
}
|
|
|
|
internal sealed record ChatProposedAction
|
|
{
|
|
[JsonPropertyName("id")]
|
|
public required string Id { get; init; }
|
|
|
|
[JsonPropertyName("tool")]
|
|
public required string Tool { get; init; }
|
|
|
|
[JsonPropertyName("description")]
|
|
public required string Description { get; init; }
|
|
|
|
[JsonPropertyName("parameters")]
|
|
public Dictionary<string, object>? Parameters { get; init; }
|
|
|
|
[JsonPropertyName("requiresConfirmation")]
|
|
public bool RequiresConfirmation { get; init; }
|
|
|
|
[JsonPropertyName("denied")]
|
|
public bool Denied { get; init; }
|
|
|
|
[JsonPropertyName("denyReason")]
|
|
public string? DenyReason { get; init; }
|
|
}
|
|
|
|
internal sealed record ChatFollowUp
|
|
{
|
|
[JsonPropertyName("suggestedQueries")]
|
|
public List<string> SuggestedQueries { get; init; } = [];
|
|
|
|
[JsonPropertyName("relatedTopics")]
|
|
public List<string> RelatedTopics { get; init; } = [];
|
|
}
|
|
|
|
internal sealed record ChatDiagnostics
|
|
{
|
|
[JsonPropertyName("tokensUsed")]
|
|
public int TokensUsed { get; init; }
|
|
|
|
[JsonPropertyName("processingTimeMs")]
|
|
public long ProcessingTimeMs { get; init; }
|
|
|
|
[JsonPropertyName("evidenceSourcesQueried")]
|
|
public int EvidenceSourcesQueried { get; init; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Chat doctor response with quota and tool access status.
|
|
/// </summary>
|
|
internal sealed record ChatDoctorResponse
|
|
{
|
|
[JsonPropertyName("tenantId")]
|
|
public required string TenantId { get; init; }
|
|
|
|
[JsonPropertyName("userId")]
|
|
public required string UserId { get; init; }
|
|
|
|
[JsonPropertyName("quotas")]
|
|
public required ChatQuotaStatus Quotas { get; init; }
|
|
|
|
[JsonPropertyName("tools")]
|
|
public required ChatToolAccess Tools { get; init; }
|
|
|
|
[JsonPropertyName("lastDenied")]
|
|
public ChatDenialInfo? LastDenied { get; init; }
|
|
}
|
|
|
|
internal sealed record ChatQuotaStatus
|
|
{
|
|
[JsonPropertyName("requestsPerMinuteLimit")]
|
|
public int RequestsPerMinuteLimit { get; init; }
|
|
|
|
[JsonPropertyName("requestsPerMinuteRemaining")]
|
|
public int RequestsPerMinuteRemaining { get; init; }
|
|
|
|
[JsonPropertyName("requestsPerMinuteResetsAt")]
|
|
public DateTimeOffset RequestsPerMinuteResetsAt { get; init; }
|
|
|
|
[JsonPropertyName("requestsPerDayLimit")]
|
|
public int RequestsPerDayLimit { get; init; }
|
|
|
|
[JsonPropertyName("requestsPerDayRemaining")]
|
|
public int RequestsPerDayRemaining { get; init; }
|
|
|
|
[JsonPropertyName("requestsPerDayResetsAt")]
|
|
public DateTimeOffset RequestsPerDayResetsAt { get; init; }
|
|
|
|
[JsonPropertyName("tokensPerDayLimit")]
|
|
public int TokensPerDayLimit { get; init; }
|
|
|
|
[JsonPropertyName("tokensPerDayRemaining")]
|
|
public int TokensPerDayRemaining { get; init; }
|
|
|
|
[JsonPropertyName("tokensPerDayResetsAt")]
|
|
public DateTimeOffset TokensPerDayResetsAt { get; init; }
|
|
}
|
|
|
|
internal sealed record ChatToolAccess
|
|
{
|
|
[JsonPropertyName("allowAll")]
|
|
public bool AllowAll { get; init; }
|
|
|
|
[JsonPropertyName("allowedTools")]
|
|
public List<string> AllowedTools { get; init; } = [];
|
|
|
|
[JsonPropertyName("providers")]
|
|
public ChatToolProviders? Providers { get; init; }
|
|
}
|
|
|
|
internal sealed record ChatToolProviders
|
|
{
|
|
[JsonPropertyName("sbom")]
|
|
public bool Sbom { get; init; }
|
|
|
|
[JsonPropertyName("vex")]
|
|
public bool Vex { get; init; }
|
|
|
|
[JsonPropertyName("reachability")]
|
|
public bool Reachability { get; init; }
|
|
|
|
[JsonPropertyName("policy")]
|
|
public bool Policy { get; init; }
|
|
|
|
[JsonPropertyName("findings")]
|
|
public bool Findings { get; init; }
|
|
}
|
|
|
|
internal sealed record ChatDenialInfo
|
|
{
|
|
[JsonPropertyName("timestamp")]
|
|
public DateTimeOffset Timestamp { get; init; }
|
|
|
|
[JsonPropertyName("reason")]
|
|
public required string Reason { get; init; }
|
|
|
|
[JsonPropertyName("code")]
|
|
public string? Code { get; init; }
|
|
|
|
[JsonPropertyName("query")]
|
|
public string? Query { get; init; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Chat settings response.
|
|
/// </summary>
|
|
internal sealed record ChatSettingsResponse
|
|
{
|
|
[JsonPropertyName("tenantId")]
|
|
public required string TenantId { get; init; }
|
|
|
|
[JsonPropertyName("userId")]
|
|
public string? UserId { get; init; }
|
|
|
|
[JsonPropertyName("scope")]
|
|
public required string Scope { get; init; }
|
|
|
|
[JsonPropertyName("quotas")]
|
|
public ChatQuotaSettings? Quotas { get; init; }
|
|
|
|
[JsonPropertyName("tools")]
|
|
public ChatToolSettings? Tools { get; init; }
|
|
|
|
[JsonPropertyName("effective")]
|
|
public ChatEffectiveSettings? Effective { get; init; }
|
|
}
|
|
|
|
internal sealed record ChatQuotaSettings
|
|
{
|
|
[JsonPropertyName("requestsPerMinute")]
|
|
public int? RequestsPerMinute { get; init; }
|
|
|
|
[JsonPropertyName("requestsPerDay")]
|
|
public int? RequestsPerDay { get; init; }
|
|
|
|
[JsonPropertyName("tokensPerDay")]
|
|
public int? TokensPerDay { get; init; }
|
|
|
|
[JsonPropertyName("toolCallsPerDay")]
|
|
public int? ToolCallsPerDay { get; init; }
|
|
}
|
|
|
|
internal sealed record ChatToolSettings
|
|
{
|
|
[JsonPropertyName("allowAll")]
|
|
public bool? AllowAll { get; init; }
|
|
|
|
[JsonPropertyName("allowedTools")]
|
|
public List<string>? AllowedTools { get; init; }
|
|
}
|
|
|
|
internal sealed record ChatEffectiveSettings
|
|
{
|
|
[JsonPropertyName("quotas")]
|
|
public required ChatQuotaSettings Quotas { get; init; }
|
|
|
|
[JsonPropertyName("tools")]
|
|
public required ChatToolSettings Tools { get; init; }
|
|
|
|
[JsonPropertyName("source")]
|
|
public required string Source { get; init; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Chat settings update request.
|
|
/// </summary>
|
|
internal sealed record ChatSettingsUpdateRequest
|
|
{
|
|
[JsonPropertyName("quotas")]
|
|
public ChatQuotaSettingsUpdate? Quotas { get; init; }
|
|
|
|
[JsonPropertyName("tools")]
|
|
public ChatToolSettingsUpdate? Tools { get; init; }
|
|
}
|
|
|
|
internal sealed record ChatQuotaSettingsUpdate
|
|
{
|
|
[JsonPropertyName("requestsPerMinute")]
|
|
public int? RequestsPerMinute { get; init; }
|
|
|
|
[JsonPropertyName("requestsPerDay")]
|
|
public int? RequestsPerDay { get; init; }
|
|
|
|
[JsonPropertyName("tokensPerDay")]
|
|
public int? TokensPerDay { get; init; }
|
|
|
|
[JsonPropertyName("toolCallsPerDay")]
|
|
public int? ToolCallsPerDay { get; init; }
|
|
}
|
|
|
|
internal sealed record ChatToolSettingsUpdate
|
|
{
|
|
[JsonPropertyName("allowAll")]
|
|
public bool? AllowAll { get; init; }
|
|
|
|
[JsonPropertyName("allowedTools")]
|
|
public List<string>? AllowedTools { get; init; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Conversation list response from AdvisoryAI conversation endpoints.
|
|
/// </summary>
|
|
internal sealed record ChatConversationListResponse
|
|
{
|
|
[JsonPropertyName("conversations")]
|
|
public List<ChatConversationSummary> Conversations { get; init; } = [];
|
|
|
|
[JsonPropertyName("totalCount")]
|
|
public int TotalCount { get; init; }
|
|
}
|
|
|
|
internal sealed record ChatConversationSummary
|
|
{
|
|
[JsonPropertyName("conversationId")]
|
|
public required string ConversationId { get; init; }
|
|
|
|
[JsonPropertyName("createdAt")]
|
|
public DateTimeOffset CreatedAt { get; init; }
|
|
|
|
[JsonPropertyName("updatedAt")]
|
|
public DateTimeOffset UpdatedAt { get; init; }
|
|
|
|
[JsonPropertyName("turnCount")]
|
|
public int TurnCount { get; init; }
|
|
|
|
[JsonPropertyName("preview")]
|
|
public string? Preview { get; init; }
|
|
}
|
|
|
|
internal sealed record ChatConversationResponse
|
|
{
|
|
[JsonPropertyName("conversationId")]
|
|
public required string ConversationId { get; init; }
|
|
|
|
[JsonPropertyName("tenantId")]
|
|
public required string TenantId { get; init; }
|
|
|
|
[JsonPropertyName("userId")]
|
|
public required string UserId { get; init; }
|
|
|
|
[JsonPropertyName("createdAt")]
|
|
public DateTimeOffset CreatedAt { get; init; }
|
|
|
|
[JsonPropertyName("updatedAt")]
|
|
public DateTimeOffset UpdatedAt { get; init; }
|
|
|
|
[JsonPropertyName("turns")]
|
|
public List<ChatConversationTurn> Turns { get; init; } = [];
|
|
}
|
|
|
|
internal sealed record ChatConversationTurn
|
|
{
|
|
[JsonPropertyName("turnId")]
|
|
public required string TurnId { get; init; }
|
|
|
|
[JsonPropertyName("role")]
|
|
public required string Role { get; init; }
|
|
|
|
[JsonPropertyName("content")]
|
|
public required string Content { get; init; }
|
|
|
|
[JsonPropertyName("timestamp")]
|
|
public DateTimeOffset Timestamp { get; init; }
|
|
|
|
[JsonPropertyName("evidenceLinks")]
|
|
public List<ChatConversationEvidenceLink>? EvidenceLinks { get; init; }
|
|
|
|
[JsonPropertyName("proposedActions")]
|
|
public List<ChatConversationProposedAction>? ProposedActions { get; init; }
|
|
}
|
|
|
|
internal sealed record ChatConversationEvidenceLink
|
|
{
|
|
[JsonPropertyName("type")]
|
|
public required string Type { get; init; }
|
|
|
|
[JsonPropertyName("uri")]
|
|
public required string Uri { get; init; }
|
|
|
|
[JsonPropertyName("label")]
|
|
public string? Label { get; init; }
|
|
|
|
[JsonPropertyName("confidence")]
|
|
public double? Confidence { get; init; }
|
|
}
|
|
|
|
internal sealed record ChatConversationProposedAction
|
|
{
|
|
[JsonPropertyName("actionType")]
|
|
public required string ActionType { get; init; }
|
|
|
|
[JsonPropertyName("label")]
|
|
public required string Label { get; init; }
|
|
|
|
[JsonPropertyName("policyGate")]
|
|
public string? PolicyGate { get; init; }
|
|
|
|
[JsonPropertyName("requiresConfirmation")]
|
|
public bool RequiresConfirmation { get; init; }
|
|
}
|
|
|
|
internal sealed record ChatConversationExport
|
|
{
|
|
[JsonPropertyName("generatedAt")]
|
|
public DateTimeOffset GeneratedAt { get; init; }
|
|
|
|
[JsonPropertyName("tenantId")]
|
|
public string? TenantId { get; init; }
|
|
|
|
[JsonPropertyName("userId")]
|
|
public string? UserId { get; init; }
|
|
|
|
[JsonPropertyName("conversationCount")]
|
|
public int ConversationCount { get; init; }
|
|
|
|
[JsonPropertyName("conversations")]
|
|
public List<ChatConversationResponse> Conversations { get; init; } = [];
|
|
}
|
|
|
|
/// <summary>
|
|
/// Error response from chat API.
|
|
/// </summary>
|
|
internal sealed record ChatErrorResponse
|
|
{
|
|
[JsonPropertyName("error")]
|
|
public required string Error { get; init; }
|
|
|
|
[JsonPropertyName("code")]
|
|
public string? Code { get; init; }
|
|
|
|
[JsonPropertyName("details")]
|
|
public Dictionary<string, object>? Details { get; init; }
|
|
|
|
[JsonPropertyName("doctor")]
|
|
public ChatDoctorAction? Doctor { get; init; }
|
|
}
|
|
|
|
internal sealed record ChatDoctorAction
|
|
{
|
|
[JsonPropertyName("endpoint")]
|
|
public required string Endpoint { get; init; }
|
|
|
|
[JsonPropertyName("suggestedCommand")]
|
|
public required string SuggestedCommand { get; init; }
|
|
|
|
[JsonPropertyName("reason")]
|
|
public required string Reason { get; init; }
|
|
}
|