use polyc_proto::proto::polychrome::state::v1 as pb;
use polyc_state::{
command::FencingToken,
digest::ContentDigest,
id::AttemptId,
model_attempt::{
ModelAttemptLifecycle, ModelAttemptReceipt, ModelAttemptRequest, ModelConversationId,
ModelPurpose, TenantId,
},
};
use crate::wire::{fixed_bytes, malformed};
pub(crate) fn request_to_wire(value: &ModelAttemptRequest) -> pb::StateModelAttemptRequest {
pb::StateModelAttemptRequest {
tenant: value.tenant().as_str().to_owned(),
conversation: value.conversation().as_str().to_owned(),
execution: value.execution().to_owned(),
claim_attempt: value.claim_attempt().as_str().to_owned(),
fence: value.fence().get(),
transport_attempt: value.transport_attempt().as_str().to_owned(),
model_attempt: value.model_attempt().as_str().to_owned(),
purpose: value.purpose().as_str().to_owned(),
request_digest: value.request_digest().as_bytes().to_vec(),
__buffa_unknown_fields: buffa::UnknownFields::default(),
}
}
pub(crate) fn request_from_wire(
value: pb::StateModelAttemptRequest,
) -> Result<ModelAttemptRequest, polyc_state::error::StateError> {
let purpose = match value.purpose.as_str() {
"answering" => ModelPurpose::Answering,
"summarization" => ModelPurpose::Summarization,
"classification" => ModelPurpose::Classification,
_ => return Err(malformed("purpose", "unknown model-attempt purpose")),
};
Ok(ModelAttemptRequest::new(
TenantId::new(value.tenant),
ModelConversationId::new(value.conversation),
value.execution,
AttemptId::new(value.claim_attempt),
FencingToken::new(value.fence),
AttemptId::new(value.transport_attempt),
AttemptId::new(value.model_attempt),
purpose,
ContentDigest::from_bytes(fixed_bytes("request_digest", &value.request_digest)?),
))
}
pub(crate) const fn lifecycle_to_wire(
value: ModelAttemptLifecycle,
) -> pb::StateModelAttemptLifecycle {
match value {
ModelAttemptLifecycle::Reserved => {
pb::StateModelAttemptLifecycle::STATE_MODEL_ATTEMPT_LIFECYCLE_RESERVED
}
ModelAttemptLifecycle::Dispatched => {
pb::StateModelAttemptLifecycle::STATE_MODEL_ATTEMPT_LIFECYCLE_DISPATCHED
}
ModelAttemptLifecycle::SettledSuccess => {
pb::StateModelAttemptLifecycle::STATE_MODEL_ATTEMPT_LIFECYCLE_SETTLED_SUCCESS
}
ModelAttemptLifecycle::SettledKnownFailure => {
pb::StateModelAttemptLifecycle::STATE_MODEL_ATTEMPT_LIFECYCLE_SETTLED_KNOWN_FAILURE
}
ModelAttemptLifecycle::Ambiguous => {
pb::StateModelAttemptLifecycle::STATE_MODEL_ATTEMPT_LIFECYCLE_AMBIGUOUS
}
ModelAttemptLifecycle::Quarantined => {
pb::StateModelAttemptLifecycle::STATE_MODEL_ATTEMPT_LIFECYCLE_QUARANTINED
}
ModelAttemptLifecycle::ReconciledSuccess => {
pb::StateModelAttemptLifecycle::STATE_MODEL_ATTEMPT_LIFECYCLE_RECONCILED_SUCCESS
}
ModelAttemptLifecycle::ReconciledFailure => {
pb::StateModelAttemptLifecycle::STATE_MODEL_ATTEMPT_LIFECYCLE_RECONCILED_FAILURE
}
}
}
pub(crate) fn lifecycle_from_wire(
value: buffa::EnumValue<pb::StateModelAttemptLifecycle>,
) -> Result<ModelAttemptLifecycle, polyc_state::error::StateError> {
match value.as_known() {
Some(pb::StateModelAttemptLifecycle::STATE_MODEL_ATTEMPT_LIFECYCLE_RESERVED) => {
Ok(ModelAttemptLifecycle::Reserved)
}
Some(pb::StateModelAttemptLifecycle::STATE_MODEL_ATTEMPT_LIFECYCLE_DISPATCHED) => {
Ok(ModelAttemptLifecycle::Dispatched)
}
Some(pb::StateModelAttemptLifecycle::STATE_MODEL_ATTEMPT_LIFECYCLE_SETTLED_SUCCESS) => {
Ok(ModelAttemptLifecycle::SettledSuccess)
}
Some(
pb::StateModelAttemptLifecycle::STATE_MODEL_ATTEMPT_LIFECYCLE_SETTLED_KNOWN_FAILURE,
) => Ok(ModelAttemptLifecycle::SettledKnownFailure),
Some(pb::StateModelAttemptLifecycle::STATE_MODEL_ATTEMPT_LIFECYCLE_AMBIGUOUS) => {
Ok(ModelAttemptLifecycle::Ambiguous)
}
Some(pb::StateModelAttemptLifecycle::STATE_MODEL_ATTEMPT_LIFECYCLE_QUARANTINED) => {
Ok(ModelAttemptLifecycle::Quarantined)
}
Some(pb::StateModelAttemptLifecycle::STATE_MODEL_ATTEMPT_LIFECYCLE_RECONCILED_SUCCESS) => {
Ok(ModelAttemptLifecycle::ReconciledSuccess)
}
Some(pb::StateModelAttemptLifecycle::STATE_MODEL_ATTEMPT_LIFECYCLE_RECONCILED_FAILURE) => {
Ok(ModelAttemptLifecycle::ReconciledFailure)
}
_ => Err(malformed("lifecycle", "unknown model-attempt lifecycle")),
}
}
pub(crate) fn receipt_to_wire(value: &ModelAttemptReceipt) -> pb::StateModelAttemptReceipt {
pb::StateModelAttemptReceipt {
version: u32::from(value.version()),
request: buffa::MessageField::some(request_to_wire(value.request())),
lifecycle: buffa::EnumValue::Known(lifecycle_to_wire(value.lifecycle())),
__buffa_unknown_fields: buffa::UnknownFields::default(),
}
}
pub(crate) fn receipt_from_wire(
value: pb::StateModelAttemptReceipt,
) -> Result<ModelAttemptReceipt, polyc_state::error::StateError> {
let request = value
.request
.into_option()
.ok_or_else(|| malformed("request", "model-attempt receipt requires request"))?;
let version = u16::try_from(value.version)
.map_err(|_| malformed("version", "model-attempt version exceeds u16"))?;
ModelAttemptReceipt::from_parts(
version,
request_from_wire(request)?,
lifecycle_from_wire(value.lifecycle)?,
)
.map_err(|error| malformed("receipt", error.to_string()))
}