#![cfg_attr(coverage_nightly, coverage(off))]
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HybridAgentSpec {
pub deterministic_core: CoreSpec,
pub probabilistic_wrapper: WrapperSpec,
pub boundary: BoundarySpec,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CoreSpec {
pub verification_method: VerificationMethod,
pub max_complexity: u32,
pub invariants: Vec<Invariant>,
}
impl CoreSpec {
#[must_use]
pub fn new() -> Self {
Self {
verification_method: VerificationMethod::PropertyTests,
max_complexity: 10,
invariants: Vec::new(),
}
}
#[must_use]
pub fn verification_method(mut self, method: VerificationMethod) -> Self {
self.verification_method = method;
self
}
#[must_use]
pub fn max_complexity(mut self, complexity: u32) -> Self {
self.max_complexity = complexity;
self
}
#[must_use]
pub fn add_invariant(mut self, invariant: Invariant) -> Self {
self.invariants.push(invariant);
self
}
}
impl Default for CoreSpec {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WrapperSpec {
pub model_type: ModelType,
pub fallback_strategy: FallbackStrategy,
pub confidence_threshold: f64,
}
impl WrapperSpec {
#[must_use]
pub fn new() -> Self {
Self {
model_type: ModelType::GPT4,
fallback_strategy: FallbackStrategy::Deterministic,
confidence_threshold: 0.95,
}
}
#[must_use]
pub fn model_type(mut self, model: ModelType) -> Self {
self.model_type = model;
self
}
#[must_use]
pub fn fallback_strategy(mut self, strategy: FallbackStrategy) -> Self {
self.fallback_strategy = strategy;
self
}
#[must_use]
pub fn confidence_threshold(mut self, threshold: f64) -> Self {
self.confidence_threshold = threshold;
self
}
}
impl Default for WrapperSpec {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BoundarySpec {
pub serialization: SerializationFormat,
pub validation: ValidationStrategy,
pub error_propagation: ErrorPropagation,
}
impl Default for BoundarySpec {
fn default() -> Self {
Self {
serialization: SerializationFormat::JSON,
validation: ValidationStrategy::Both,
error_propagation: ErrorPropagation::Immediate,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum VerificationMethod {
PropertyTests,
FormalProof,
ModelChecking,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum ModelType {
GPT4,
Claude,
Local(String),
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum FallbackStrategy {
Deterministic,
DefaultValue,
Error,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum SerializationFormat {
JSON,
MessagePack,
Protobuf,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ValidationStrategy {
Schema,
Runtime,
Both,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ErrorPropagation {
Immediate,
Deferred,
Logged,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Invariant {
pub name: String,
pub description: String,
pub severity: InvariantSeverity,
}
impl Invariant {
pub fn new(name: impl Into<String>, description: impl Into<String>) -> Self {
Self {
name: name.into(),
description: description.into(),
severity: InvariantSeverity::Error,
}
}
#[must_use]
pub fn with_severity(mut self, severity: InvariantSeverity) -> Self {
self.severity = severity;
self
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum InvariantSeverity {
Warning,
Error,
Critical,
}
#[must_use]
pub fn validate_complexity_for_quality(
spec: &CoreSpec,
quality: crate::scaffold::QualityLevel,
) -> bool {
spec.max_complexity <= quality.max_complexity()
}
#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_core_spec_builder() {
let spec = CoreSpec::new()
.verification_method(VerificationMethod::FormalProof)
.max_complexity(5)
.add_invariant(Invariant::new("test", "Test invariant"));
assert!(matches!(
spec.verification_method,
VerificationMethod::FormalProof
));
assert_eq!(spec.max_complexity, 5);
assert_eq!(spec.invariants.len(), 1);
}
#[test]
fn test_wrapper_spec_builder() {
let spec = WrapperSpec::new()
.model_type(ModelType::Claude)
.fallback_strategy(FallbackStrategy::Error)
.confidence_threshold(0.9);
assert!(matches!(spec.model_type, ModelType::Claude));
assert!(matches!(spec.fallback_strategy, FallbackStrategy::Error));
assert_eq!(spec.confidence_threshold, 0.9);
}
#[test]
fn test_hybrid_spec_serialization() {
let spec = HybridAgentSpec {
deterministic_core: CoreSpec::default(),
probabilistic_wrapper: WrapperSpec::default(),
boundary: BoundarySpec::default(),
};
let json = serde_json::to_string(&spec).unwrap();
let deserialized: HybridAgentSpec = serde_json::from_str(&json).unwrap();
assert_eq!(
deserialized.deterministic_core.max_complexity,
spec.deterministic_core.max_complexity
);
}
#[test]
fn test_validate_complexity() {
let spec = CoreSpec::new().max_complexity(8);
assert!(validate_complexity_for_quality(
&spec,
crate::scaffold::QualityLevel::Extreme
));
let spec = CoreSpec::new().max_complexity(15);
assert!(!validate_complexity_for_quality(
&spec,
crate::scaffold::QualityLevel::Extreme
));
}
}
#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod property_tests {
use proptest::prelude::*;
proptest! {
#[test]
fn basic_property_stability(_input in ".*") {
prop_assert!(true);
}
#[test]
fn module_consistency_check(_x in 0u32..1000) {
prop_assert!(_x < 1001);
}
}
}