Files
git.stella-ops.org/src/Cli/StellaOps.Cli/Services/Models/Chat/ChatModels.cs

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; }
}