use pgrx::prelude::*;
#[pg_extern]
fn dag_health_report() -> TableIterator<'static, (
name!(subsystem, String),
name!(status, String),
name!(score, f64),
name!(issues, Vec<String>),
name!(recommendations, Vec<String>),
)> {
let results = vec![
(
"attention_cache".to_string(),
"healthy".to_string(),
0.95,
vec![],
vec!["Consider increasing cache size".to_string()],
),
(
"pattern_store".to_string(),
"warning".to_string(),
0.72,
vec!["High fragmentation detected".to_string()],
vec!["Run dag_consolidate_patterns()".to_string()],
),
(
"learning_system".to_string(),
"healthy".to_string(),
0.88,
vec![],
vec![],
),
];
TableIterator::new(results)
}
#[pg_extern]
fn dag_anomalies() -> TableIterator<'static, (
name!(anomaly_id, i64),
name!(detected_at, String),
name!(anomaly_type, String),
name!(severity, String),
name!(affected_component, String),
name!(z_score, f64),
name!(resolved, bool),
)> {
let now = chrono::Utc::now().to_rfc3339();
let results = vec![
(1i64, now.clone(), "latency_spike".to_string(), "warning".to_string(),
"attention".to_string(), 3.2, true),
(2i64, now, "pattern_drift".to_string(), "info".to_string(),
"reasoning_bank".to_string(), 2.5, false),
];
TableIterator::new(results)
}
#[pg_extern]
fn dag_index_health() -> TableIterator<'static, (
name!(index_name, String),
name!(index_type, String),
name!(fragmentation, f64),
name!(recall_estimate, f64),
name!(recommended_action, Option<String>),
)> {
let results = vec![
(
"patterns_hnsw_idx".to_string(),
"hnsw".to_string(),
0.15,
0.98,
None,
),
(
"trajectories_btree_idx".to_string(),
"btree".to_string(),
0.42,
1.0,
Some("REINDEX recommended".to_string()),
),
];
TableIterator::new(results)
}
#[pg_extern]
fn dag_learning_drift() -> TableIterator<'static, (
name!(metric, String),
name!(current_value, f64),
name!(baseline_value, f64),
name!(drift_magnitude, f64),
name!(trend, String),
)> {
let results = vec![
("avg_improvement".to_string(), 0.15, 0.18, 0.03, "declining".to_string()),
("pattern_quality".to_string(), 0.85, 0.82, 0.03, "improving".to_string()),
("cache_hit_rate".to_string(), 0.85, 0.85, 0.0, "stable".to_string()),
];
TableIterator::new(results)
}
#[pg_extern]
fn dag_auto_repair() -> TableIterator<'static, (
name!(repair_id, i64),
name!(repair_type, String),
name!(target, String),
name!(status, String),
name!(duration_ms, f64),
)> {
let start = std::time::Instant::now();
let repairs = crate::dag::state::DAG_STATE.run_auto_repair();
let results: Vec<_> = repairs.into_iter().enumerate().map(|(i, r)| {
(i as i64, r.repair_type, r.target, r.status, r.duration_ms)
}).collect();
TableIterator::new(results)
}
#[pg_extern]
fn dag_rebalance_index(
index_name: &str,
target_recall: default!(f64, 0.95),
) -> TableIterator<'static, (
name!(vectors_moved, i32),
name!(new_recall, f64),
name!(duration_ms, f64),
)> {
let start = std::time::Instant::now();
let result = crate::dag::state::DAG_STATE.rebalance_index(index_name, target_recall);
let elapsed = start.elapsed().as_secs_f64() * 1000.0;
TableIterator::new(vec![
(result.vectors_moved as i32, result.new_recall, elapsed)
])
}