use serde::{Deserialize, Serialize};
#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
pub struct CompletionRequirement {
max_terminal_repairs: u32,
retry_empty_response: bool,
}
impl CompletionRequirement {
pub const fn new() -> Self {
Self {
max_terminal_repairs: 0,
retry_empty_response: false,
}
}
#[must_use]
pub const fn max_repairs(mut self, maximum: u32) -> Self {
self.max_terminal_repairs = maximum;
self
}
#[must_use]
pub const fn retry_empty_response(mut self, enabled: bool) -> Self {
self.retry_empty_response = enabled;
self
}
pub const fn max_terminal_repairs(self) -> u32 {
self.max_terminal_repairs
}
pub const fn retries_empty_response(self) -> bool {
self.retry_empty_response
}
}
#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
pub enum TerminalRequirementFailureKind {
EmptyResponse,
MissingStructuredText,
InvalidStructuredOutput,
Refusal,
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct TerminalRequirementFailure {
pub kind: TerminalRequirementFailureKind,
pub line: Option<usize>,
pub column: Option<usize>,
}
impl TerminalRequirementFailure {
pub(crate) const fn new(kind: TerminalRequirementFailureKind) -> Self {
Self {
kind,
line: None,
column: None,
}
}
pub(crate) const fn repairable(&self, policy: CompletionRequirement) -> bool {
match self.kind {
TerminalRequirementFailureKind::EmptyResponse
| TerminalRequirementFailureKind::MissingStructuredText => {
policy.retries_empty_response()
}
TerminalRequirementFailureKind::InvalidStructuredOutput => true,
TerminalRequirementFailureKind::Refusal => false,
}
}
}