use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InterleavedStep {
pub step_id: String,
pub description: String,
pub reasoning_chain: Vec<ReasoningNode>,
pub cross_validation_passed: bool,
pub confidence: f64,
pub validation_results: Vec<ValidationResult>,
pub dependencies: Vec<String>,
pub estimated_duration_ms: u32,
pub actual_duration_ms: Option<u32>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ReasoningNode {
pub node_id: String,
pub content: String,
pub reasoning_type: ReasoningType,
pub confidence: f64,
pub supporting_evidence: Vec<Evidence>,
pub next_steps: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum ReasoningType {
Deductive,
Inductive,
Abductive,
Analogical,
FirstPrinciples,
Counterfactual,
Synthesis,
Analysis,
Evaluation,
Creative,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Evidence {
pub evidence_id: String,
pub source: EvidenceSource,
pub reliability: f64,
pub relevance: f64,
pub content: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum EvidenceSource {
External(String),
Internal(InternalSource),
Synthetic(SyntheticSource),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum InternalSource {
PreviousStep(String),
CachedResult(String),
UserInput,
SystemContext,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum SyntheticSource {
LogicalInference,
PatternRecognition,
Heuristic,
Assumption,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ValidationResult {
pub validation_id: String,
pub validation_type: ValidationType,
pub passed: bool,
pub confidence_score: f64,
pub details: String,
pub recommendations: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ValidationType {
LogicalConsistency,
FactCheck,
Coherence,
Completeness,
Plausibility,
CrossReference,
ConstraintCompliance,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CrossValidation {
pub validation_id: String,
pub primary_step: String,
pub validating_steps: Vec<String>,
pub validation_rules: Vec<ValidationRule>,
pub result: CrossValidationResult,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CrossValidationResult {
pub overall_passed: bool,
pub confidence_score: f64,
pub discrepancies: Vec<Discrepancy>,
pub agreement_metrics: AgreementMetrics,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Discrepancy {
pub discrepancy_id: String,
pub step_involved: String,
pub description: String,
pub severity: DiscrepancySeverity,
pub suggested_resolution: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum DiscrepancySeverity {
Low,
Medium,
High,
Critical,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AgreementMetrics {
pub semantic_similarity: f64,
pub logical_consistency: f64,
pub factual_alignment: f64,
pub confidence_convergence: f64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ThinkingPattern {
pub pattern_id: String,
pub name: String,
pub description: String,
pub pattern_type: PatternType,
pub steps: Vec<PatternStep>,
pub validation_rules: Vec<ValidationRule>,
pub optimization_params: OptimizationParameters,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum PatternType {
Linear,
Branching,
Iterative,
Parallel,
Hierarchical,
Cyclical,
Adaptive,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PatternStep {
pub step_id: String,
pub step_type: PatternStepType,
pub description: String,
pub prerequisites: Vec<String>,
pub outputs: Vec<StepOutput>,
pub validation_criteria: Vec<ValidationCriterion>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum PatternStepType {
InputProcessing,
Reasoning,
Validation,
Synthesis,
Decision,
OutputGeneration,
Analysis,
Evaluation,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct StepOutput {
pub output_id: String,
pub content_type: OutputContentType,
pub format: OutputFormat,
pub validation_required: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum OutputContentType {
Text,
Structured,
Numerical,
Logical,
Creative,
Analytical,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum OutputFormat {
PlainText,
JSON,
YAML,
Markdown,
Table,
Graph,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ValidationCriterion {
pub criterion_id: String,
pub check_type: CheckType,
pub threshold: f64,
pub description: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum CheckType {
MinimumLength,
MaximumLength,
ConfidenceThreshold,
LogicalConsistency,
FactualAccuracy,
Completeness,
}
pub struct MultiStepReasoning {
pub reasoning_id: String,
pub pattern: ThinkingPattern,
pub current_step_index: usize,
pub completed_steps: Vec<InterleavedStep>,
pub pending_steps: Vec<PatternStep>,
pub cross_validations: Vec<CrossValidation>,
pub state: ReasoningState,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ReasoningState {
pub status: ReasoningStatus,
pub progress: f64,
pub confidence: f64,
pub errors: Vec<ReasoningError>,
pub warnings: Vec<ReasoningWarning>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ReasoningStatus {
Initializing,
InProgress,
Validating,
Completing,
Completed,
Failed,
Paused,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ReasoningError {
pub error_id: String,
pub step_id: Option<String>,
pub error_type: ErrorType,
pub message: String,
pub severity: ErrorSeverity,
pub suggested_action: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ErrorType {
ValidationFailure,
DependencyNotMet,
Timeout,
ResourceExhaustion,
LogicError,
DataInconsistency,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ErrorSeverity {
Info,
Warning,
Error,
Critical,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ReasoningWarning {
pub warning_id: String,
pub step_id: Option<String>,
pub message: String,
pub impact: WarningImpact,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum WarningImpact {
Low,
Medium,
High,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ValidationRule {
pub rule_id: String,
pub rule_type: RuleType,
pub parameters: HashMap<String, serde_json::Value>,
pub description: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum RuleType {
SequenceConstraint,
ResourceLimit,
QualityThreshold,
DependencyCheck,
ConsistencyRule,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OptimizationParameters {
pub max_iterations: Option<u32>,
pub confidence_threshold: f64,
pub time_limit_ms: Option<u32>,
pub token_limit: Option<u32>,
pub parallelization_level: u32,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InterleavedProtocol {
pub protocol_id: String,
pub name: String,
pub version: String,
pub description: String,
pub patterns: Vec<ThinkingPattern>,
pub default_pattern: String,
pub optimization_config: ProtocolOptimization,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ProtocolOptimization {
pub auto_validation: bool,
pub cross_validation_enabled: bool,
pub parallel_processing: bool,
pub adaptive_patterns: bool,
pub performance_target: f64,
pub cost_optimization: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InterleavedResult {
pub result_id: String,
pub protocol_id: String,
pub pattern_used: String,
pub status: InterleavedStatus,
pub final_confidence: f64,
pub steps_completed: Vec<InterleavedStep>,
pub cross_validations_performed: Vec<CrossValidation>,
pub performance_metrics: InterleavedPerformance,
pub recommendations: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum InterleavedStatus {
Success,
PartialSuccess,
ValidationFailed,
Timeout,
ResourceExceeded,
Incomplete,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InterleavedPerformance {
pub total_time_ms: u64,
pub token_count: u32,
pub steps_executed: u32,
pub validations_passed: u32,
pub validations_failed: u32,
pub cross_validation_score: f64,
pub efficiency_score: f64,
}
impl MultiStepReasoning {
pub fn new(pattern: ThinkingPattern) -> Self {
Self {
reasoning_id: uuid::Uuid::new_v4().to_string(),
pattern,
current_step_index: 0,
completed_steps: Vec::new(),
pending_steps: Vec::new(),
cross_validations: Vec::new(),
state: ReasoningState {
status: ReasoningStatus::Initializing,
progress: 0.0,
confidence: 0.0,
errors: Vec::new(),
warnings: Vec::new(),
},
}
}
pub async fn execute(&mut self, input: &str) -> Result<InterleavedResult, crate::error::Error> {
self.state.status = ReasoningStatus::InProgress;
self.pending_steps = self.pattern.steps.clone();
while !self.pending_steps.is_empty() && self.current_step_index < self.pattern.steps.len() {
let current_step = &self.pattern.steps[self.current_step_index];
let step_result = self.execute_step(current_step, input).await?;
self.completed_steps.push(step_result);
if self.should_cross_validate() {
self.perform_cross_validation().await?;
}
self.current_step_index += 1;
self.update_progress();
}
let final_result = self.synthesize_results().await?;
self.state.status = ReasoningStatus::Completed;
Ok(final_result)
}
async fn execute_step(
&self,
step: &PatternStep,
input: &str,
) -> Result<InterleavedStep, crate::error::Error> {
let start_time = std::time::Instant::now();
for prereq in &step.prerequisites {
if !self.has_completed_step(prereq) {
return Err(crate::error::Error::Validation(format!(
"Prerequisite step '{}' not completed",
prereq
)));
}
}
let reasoning_chain = self.generate_reasoning_chain(step, input).await?;
let validation_results = self.validate_step_output(step, &reasoning_chain).await?;
let actual_duration = start_time.elapsed().as_millis() as u32;
Ok(InterleavedStep {
step_id: step.step_id.clone(),
description: step.description.clone(),
reasoning_chain,
cross_validation_passed: validation_results.iter().all(|r| r.passed),
confidence: self.calculate_step_confidence(&validation_results),
validation_results,
dependencies: step.prerequisites.clone(),
estimated_duration_ms: 100, actual_duration_ms: Some(actual_duration),
})
}
async fn generate_reasoning_chain(
&self,
step: &PatternStep,
input: &str,
) -> Result<Vec<ReasoningNode>, crate::error::Error> {
let mut chain = Vec::new();
match step.step_type {
PatternStepType::InputProcessing => {
chain.push(ReasoningNode {
node_id: uuid::Uuid::new_v4().to_string(),
content: format!("Processing input: {}", input),
reasoning_type: ReasoningType::Analysis,
confidence: 0.9,
supporting_evidence: vec![],
next_steps: vec![],
});
}
PatternStepType::Reasoning => {
let node = ReasoningNode {
node_id: uuid::Uuid::new_v4().to_string(),
content: self.generate_reasoning_content(step, input).await?,
reasoning_type: ReasoningType::Deductive,
confidence: 0.8,
supporting_evidence: vec![],
next_steps: vec![],
};
chain.push(node);
}
PatternStepType::Validation => {
chain.push(ReasoningNode {
node_id: uuid::Uuid::new_v4().to_string(),
content: "Performing validation checks".to_string(),
reasoning_type: ReasoningType::Evaluation,
confidence: 0.85,
supporting_evidence: vec![],
next_steps: vec![],
});
}
_ => {
chain.push(ReasoningNode {
node_id: uuid::Uuid::new_v4().to_string(),
content: format!("Executing {} step", step.step_type.clone() as i32),
reasoning_type: ReasoningType::Analysis,
confidence: 0.7,
supporting_evidence: vec![],
next_steps: vec![],
});
}
}
Ok(chain)
}
fn should_cross_validate(&self) -> bool {
self.pattern.optimization_params.parallelization_level > 1
}
fn has_completed_step(&self, step_id: &str) -> bool {
self.completed_steps
.iter()
.any(|step| step.step_id == step_id)
}
fn calculate_step_confidence(&self, validations: &[ValidationResult]) -> f64 {
if validations.is_empty() {
return 0.7; }
validations.iter().map(|v| v.confidence_score).sum::<f64>() / validations.len() as f64
}
async fn generate_reasoning_content(
&self,
step: &PatternStep,
input: &str,
) -> Result<String, crate::error::Error> {
Ok(format!(
"Reasoning for step '{}' based on input: {}",
step.step_id, input
))
}
async fn validate_step_output(
&self,
step: &PatternStep,
chain: &[ReasoningNode],
) -> Result<Vec<ValidationResult>, crate::error::Error> {
let mut validations = Vec::new();
for criterion in &step.validation_criteria {
let validation = match criterion.check_type {
CheckType::MinimumLength => {
let content = chain
.iter()
.map(|n| n.content.as_str())
.collect::<Vec<_>>()
.join(" ");
let passed = content.len() >= (criterion.threshold as usize);
ValidationResult {
validation_id: uuid::Uuid::new_v4().to_string(),
validation_type: ValidationType::Completeness,
passed,
confidence_score: if passed { 0.9 } else { 0.3 },
details: format!(
"Content length: {} vs threshold: {}",
content.len(),
criterion.threshold
),
recommendations: if !passed {
vec!["Increase detail level".to_string()]
} else {
vec![]
},
}
}
CheckType::ConfidenceThreshold => {
let avg_confidence =
chain.iter().map(|n| n.confidence).sum::<f64>() / chain.len() as f64;
let passed = avg_confidence >= criterion.threshold;
ValidationResult {
validation_id: uuid::Uuid::new_v4().to_string(),
validation_type: ValidationType::Coherence,
passed,
confidence_score: avg_confidence,
details: format!(
"Average confidence: {} vs threshold: {}",
avg_confidence, criterion.threshold
),
recommendations: if !passed {
vec!["Improve confidence through better evidence".to_string()]
} else {
vec![]
},
}
}
_ => ValidationResult {
validation_id: uuid::Uuid::new_v4().to_string(),
validation_type: ValidationType::Completeness,
passed: true,
confidence_score: 0.8,
details: "Default validation passed".to_string(),
recommendations: vec![],
},
};
validations.push(validation);
}
Ok(validations)
}
async fn perform_cross_validation(&mut self) -> Result<(), crate::error::Error> {
Ok(())
}
fn update_progress(&mut self) {
self.state.progress =
(self.completed_steps.len() as f64 / self.pattern.steps.len() as f64) * 100.0;
if !self.completed_steps.is_empty() {
self.state.confidence = self
.completed_steps
.iter()
.map(|step| step.confidence)
.sum::<f64>()
/ self.completed_steps.len() as f64;
}
}
async fn synthesize_results(&self) -> Result<InterleavedResult, crate::error::Error> {
let total_time = self
.completed_steps
.iter()
.filter_map(|step| step.actual_duration_ms)
.sum::<u32>() as u64;
let validations_passed = self
.completed_steps
.iter()
.flat_map(|step| &step.validation_results)
.filter(|v| v.passed)
.count() as u32;
let validations_failed = self
.completed_steps
.iter()
.flat_map(|step| &step.validation_results)
.filter(|v| !v.passed)
.count() as u32;
let cross_validation_score = if !self.cross_validations.is_empty() {
self.cross_validations
.iter()
.map(|cv| cv.result.confidence_score)
.sum::<f64>()
/ self.cross_validations.len() as f64
} else {
0.8 };
Ok(InterleavedResult {
result_id: uuid::Uuid::new_v4().to_string(),
protocol_id: self.pattern.pattern_id.clone(),
pattern_used: self.pattern.name.clone(),
status: if validations_failed > 0 {
InterleavedStatus::PartialSuccess
} else {
InterleavedStatus::Success
},
final_confidence: self.state.confidence,
steps_completed: self.completed_steps.clone(),
cross_validations_performed: self.cross_validations.clone(),
performance_metrics: InterleavedPerformance {
total_time_ms: total_time,
token_count: (total_time / 10) as u32, steps_executed: self.completed_steps.len() as u32,
validations_passed,
validations_failed,
cross_validation_score,
efficiency_score: self.calculate_efficiency_score(
total_time,
validations_passed,
validations_failed,
),
},
recommendations: self.generate_recommendations(),
})
}
fn calculate_efficiency_score(&self, time_ms: u64, passed: u32, failed: u32) -> f64 {
let total_validations = passed + failed;
if total_validations == 0 {
return 0.5;
}
let success_rate = passed as f64 / total_validations as f64;
let time_factor = (5000.0 / time_ms as f64).min(2.0);
(success_rate * 0.7 + (time_factor - 1.0) * 0.3).clamp(0.0, 1.0)
}
fn generate_recommendations(&self) -> Vec<String> {
let mut recommendations = Vec::new();
if self.state.confidence < 0.8 {
recommendations
.push("Consider additional validation steps to improve confidence".to_string());
}
if self.completed_steps.len() < self.pattern.steps.len() {
recommendations.push("Some pattern steps were not completed".to_string());
}
if let Some(error) = self.state.errors.first() {
recommendations.push(format!("Address error: {}", error.message));
}
recommendations
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_interleaved_step_creation() {
let step = InterleavedStep {
step_id: "test_step".to_string(),
description: "Test step".to_string(),
reasoning_chain: vec![],
cross_validation_passed: false,
confidence: 0.8,
validation_results: vec![],
dependencies: vec![],
estimated_duration_ms: 100,
actual_duration_ms: None,
};
assert_eq!(step.step_id, "test_step");
assert_eq!(step.confidence, 0.8);
}
#[test]
fn test_thinking_pattern_creation() {
let pattern = ThinkingPattern {
pattern_id: "test_pattern".to_string(),
name: "Test Pattern".to_string(),
description: "A test thinking pattern".to_string(),
pattern_type: PatternType::Linear,
steps: vec![],
validation_rules: vec![],
optimization_params: OptimizationParameters {
max_iterations: Some(10),
confidence_threshold: 0.8,
time_limit_ms: Some(5000),
token_limit: Some(2000),
parallelization_level: 1,
},
};
assert_eq!(pattern.pattern_id, "test_pattern");
assert_eq!(pattern.optimization_params.confidence_threshold, 0.8);
}
}