use serde::{Deserialize, Serialize};
use std::sync::atomic::{AtomicU64, Ordering};
use super::error::{Result, RuvLlmIntegrationError};
#[derive(Debug)]
pub struct PolicyBridge {
config: PolicyBridgeConfig,
syncs: AtomicU64,
sync_failures: AtomicU64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PolicyBridgeConfig {
pub auto_sync: bool,
pub sync_interval_secs: u64,
pub batch_size: usize,
pub bidirectional: bool,
pub conflict_resolution: ConflictResolution,
}
impl Default for PolicyBridgeConfig {
fn default() -> Self {
Self {
auto_sync: true,
sync_interval_secs: 60,
batch_size: 100,
bidirectional: true,
conflict_resolution: ConflictResolution::PreferNewest,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
pub enum ConflictResolution {
#[default]
PreferNewest,
PreferPrimeRadiant,
PreferRuvLlm,
Merge,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PolicySyncResult {
pub to_ruvllm: usize,
pub to_prime_radiant: usize,
pub conflicts_resolved: usize,
pub duration_ms: u64,
pub timestamp: chrono::DateTime<chrono::Utc>,
}
impl PolicyBridge {
pub fn new(config: PolicyBridgeConfig) -> Result<Self> {
Ok(Self {
config,
syncs: AtomicU64::new(0),
sync_failures: AtomicU64::new(0),
})
}
pub fn sync_policies(&self) -> Result<PolicySyncResult> {
let start = std::time::Instant::now();
self.syncs.fetch_add(1, Ordering::Relaxed);
Ok(PolicySyncResult {
to_ruvllm: 0,
to_prime_radiant: 0,
conflicts_resolved: 0,
duration_ms: start.elapsed().as_millis() as u64,
timestamp: chrono::Utc::now(),
})
}
pub fn config(&self) -> &PolicyBridgeConfig {
&self.config
}
pub fn stats(&self) -> (u64, u64) {
(
self.syncs.load(Ordering::Relaxed),
self.sync_failures.load(Ordering::Relaxed),
)
}
}
#[derive(Debug)]
pub struct SonaBridge {
config: SonaBridgeConfig,
feedback_processed: AtomicU64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SonaBridgeConfig {
pub enable_feedback: bool,
pub batch_size: usize,
pub learning_rate_multiplier: f64,
pub sync_ewc: bool,
pub share_lora_weights: bool,
}
impl Default for SonaBridgeConfig {
fn default() -> Self {
Self {
enable_feedback: true,
batch_size: 32,
learning_rate_multiplier: 1.0,
sync_ewc: true,
share_lora_weights: false,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LearningFeedback {
pub source: FeedbackSource,
pub feedback_type: FeedbackType,
pub timestamp: chrono::DateTime<chrono::Utc>,
pub session_id: Option<String>,
pub success: bool,
pub coherence_energy: Option<f64>,
pub quality_score: Option<f64>,
pub context: serde_json::Value,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum FeedbackSource {
PrimeRadiant,
RuvLlm,
Human,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum FeedbackType {
CoherenceResult,
QualityFeedback,
GateDecision,
HumanCorrection,
ThresholdAdjustment,
}
impl SonaBridge {
pub fn new(config: SonaBridgeConfig) -> Result<Self> {
Ok(Self {
config,
feedback_processed: AtomicU64::new(0),
})
}
pub fn process_feedback(&self, feedback: LearningFeedback) -> Result<()> {
if !self.config.enable_feedback {
return Ok(());
}
self.validate_feedback(&feedback)?;
self.feedback_processed.fetch_add(1, Ordering::Relaxed);
Ok(())
}
fn validate_feedback(&self, feedback: &LearningFeedback) -> Result<()> {
if feedback.coherence_energy.is_none() && feedback.quality_score.is_none() {
return Err(RuvLlmIntegrationError::Config(
"Feedback must contain either coherence_energy or quality_score".to_string(),
));
}
Ok(())
}
pub fn config(&self) -> &SonaBridgeConfig {
&self.config
}
pub fn feedback_count(&self) -> u64 {
self.feedback_processed.load(Ordering::Relaxed)
}
}
impl LearningFeedback {
pub fn coherence(energy: f64, success: bool) -> Self {
Self {
source: FeedbackSource::PrimeRadiant,
feedback_type: FeedbackType::CoherenceResult,
timestamp: chrono::Utc::now(),
session_id: None,
success,
coherence_energy: Some(energy),
quality_score: None,
context: serde_json::Value::Null,
}
}
pub fn quality(score: f64, success: bool) -> Self {
Self {
source: FeedbackSource::RuvLlm,
feedback_type: FeedbackType::QualityFeedback,
timestamp: chrono::Utc::now(),
session_id: None,
success,
coherence_energy: None,
quality_score: Some(score),
context: serde_json::Value::Null,
}
}
pub fn human_correction(success: bool, context: serde_json::Value) -> Self {
Self {
source: FeedbackSource::Human,
feedback_type: FeedbackType::HumanCorrection,
timestamp: chrono::Utc::now(),
session_id: None,
success,
coherence_energy: None,
quality_score: None,
context,
}
}
pub fn with_session(mut self, session_id: String) -> Self {
self.session_id = Some(session_id);
self
}
}