using System.Text.Json.Serialization; using AnthropicClient.Utils; namespace AnthropicClient.Models; /// /// Represents a message request. /// public abstract class BaseMessageRequest { /// /// Gets the model ID to use for the request. /// public string Model { get; init; } = string.Empty; /// /// Gets the system message that will be used as the system prompt if no system messages are provided. /// [JsonIgnore] public string? System { get; init; } = null; /// /// Gets the system messages to send to the model to be used as the system prompt. /// [JsonIgnore] public List? SystemMessages { get; init; } = null; /// /// Gets the system prompt that will be used for the request. /// If will return the system messages if they are provided, otherwise it will return the system message. /// If neither are provided, it will return null. /// [JsonPropertyName("system")] public List? SystemPrompt => GetSystemPrompt(); private List? GetSystemPrompt() { if (SystemMessages is not null) { return SystemMessages; } if (System is not null) { return [new TextContent(System)]; } return null; } /// /// Gets the messages to send to the model. /// public List Messages { get; init; } = []; /// /// Gets the maximum number of tokens to generate. /// [JsonPropertyName("max_tokens")] public int MaxTokens { get; init; } = 1024; /// /// Gets the metadata to include with the request. /// public Dictionary? Metadata { get; init; } = null; /// /// Gets the prompt stop sequences. /// [JsonPropertyName("stop_sequences")] public List StopSequences { get; init; } = []; /// /// Gets the temperature to use for the request. /// public decimal Temperature { get; init; } = 0.0m; /// /// Gets the top-K value to use for the request. /// public int? TopK { get; init; } = null; /// /// Gets the top-P value to use for the request. /// public decimal? TopP { get; init; } = null; /// /// Gets the tool choice mode to use for the request. /// [JsonPropertyName("tool_choice")] public ToolChoice? ToolChoice { get; init; } = null; /// /// Gets the tools to use for the request. /// public List? Tools { get; init; } = null; /// /// Gets a value indicating whether the message should be streamed. /// public bool Stream { get; init; } [JsonConstructor] internal BaseMessageRequest() { } private BaseMessageRequest( string model, List messages, int maxTokens, string? system, List? systemMessages, Dictionary? metadata, decimal temperature, int? topK, decimal? topP, ToolChoice? toolChoice, List? tools, bool stream, List? stopSequences ) { ArgumentValidator.ThrowIfNull(model, nameof(model)); ArgumentValidator.ThrowIfNull(messages, nameof(messages)); if (AnthropicModels.IsValidModel(model) is false) { throw new ArgumentException($"Invalid model ID: {model}"); } if (messages.Count < 1) { throw new ArgumentException("Messages must contain at least one message"); } if (maxTokens < 1) { throw new ArgumentException($"Invalid max tokens: {maxTokens}"); } if (temperature < 0.0m || temperature > 1.0m) { throw new ArgumentException($"Invalid temperature: {temperature}"); } Model = model; Messages = messages; MaxTokens = maxTokens; System = system; SystemMessages = systemMessages; Metadata = metadata; Temperature = temperature; TopK = topK; TopP = topP; ToolChoice = toolChoice; Tools = tools; Stream = stream; StopSequences = stopSequences ?? []; } /// /// Initializes a new instance of the class. /// /// The model ID to use for the request. /// The messages to send to the model. /// The maximum number of tokens to generate. /// The system prompt to use for the request. /// The metadata to include with the request. /// The temperature to use for the request. /// The top-K value to use for the request. /// The top-P value to use for the request. /// The tool choice mode to use for the request. /// The tools to use for the request. /// A value indicating whether the message should be streamed. /// The prompt stop sequences. /// Thrown when the model ID is invalid. /// Thrown when the model or messages is null. /// Thrown when the messages contain no messages. /// Thrown when the max tokens is less than one. /// Thrown when the temperature is less than zero or greater than one. /// A new instance of the class. protected BaseMessageRequest( string model, List messages, int maxTokens = 1024, string? system = null, Dictionary? metadata = null, decimal temperature = 0.0m, int? topK = null, decimal? topP = null, ToolChoice? toolChoice = null, List? tools = null, bool stream = false, List? stopSequences = null ) : this( model, messages, maxTokens, system, null, metadata, temperature, topK, topP, toolChoice, tools, stream, stopSequences ) { } /// /// Initializes a new instance of the class. /// /// The model ID to use for the request. /// The messages to send to the model. /// The maximum number of tokens to generate. /// The system messages to send to the model to be used as the system prompt. /// The metadata to include with the request. /// The temperature to use for the request. /// The top-K value to use for the request. /// The top-P value to use for the request. /// The tool choice mode to use for the request. /// The tools to use for the request. /// A value indicating whether the message should be streamed. /// The prompt stop sequences. /// Thrown when the model ID is invalid. /// Thrown when the model or messages is null. /// Thrown when the messages contain no messages. /// Thrown when the max tokens is less than one. /// Thrown when the temperature is less than zero or greater than one. /// A new instance of the class. protected BaseMessageRequest( string model, List messages, int maxTokens = 1024, List? systemMessages = null, Dictionary? metadata = null, decimal temperature = 0.0m, int? topK = null, decimal? topP = null, ToolChoice? toolChoice = null, List? tools = null, bool stream = false, List? stopSequences = null ) : this( model, messages, maxTokens, null, systemMessages, metadata, temperature, topK, topP, toolChoice, tools, stream, stopSequences ) { } }