agentic_connect/types/
soul.rs1use chrono::{DateTime, Utc};
4use serde::{Deserialize, Serialize};
5use std::collections::HashMap;
6
7use super::connection::ConnectionId;
8
9#[derive(Debug, Clone, Serialize, Deserialize)]
11pub struct ConnectionProfile {
12 pub connection_id: ConnectionId,
13 pub fingerprint: SystemFingerprint,
14 pub baseline: PerformanceBaseline,
15 pub error_history: Vec<ErrorRecord>,
16 pub capabilities: HashMap<String, String>,
17 pub first_seen: DateTime<Utc>,
18 pub last_updated: DateTime<Utc>,
19 pub connection_count: u64,
20}
21
22#[derive(Debug, Clone, Default, Serialize, Deserialize)]
24pub struct SystemFingerprint {
25 pub os: Option<String>,
26 pub os_version: Option<String>,
27 pub server_software: Option<String>,
28 pub server_version: Option<String>,
29 pub tls_version: Option<String>,
30 pub supported_protocols: Vec<String>,
31 pub detected_services: Vec<String>,
32 pub timezone: Option<String>,
33}
34
35#[derive(Debug, Clone, Default, Serialize, Deserialize)]
37pub struct PerformanceBaseline {
38 pub avg_latency_ms: f64,
39 pub p50_latency_ms: f64,
40 pub p95_latency_ms: f64,
41 pub p99_latency_ms: f64,
42 pub avg_throughput_bps: f64,
43 pub error_rate: f64,
44 pub sample_count: u64,
45 pub last_measured: Option<DateTime<Utc>>,
46}
47
48#[derive(Debug, Clone, Serialize, Deserialize)]
50pub struct ErrorRecord {
51 pub timestamp: DateTime<Utc>,
52 pub error_type: String,
53 pub error_message: String,
54 pub http_status: Option<u16>,
55 pub resolved: bool,
56}
57
58impl ConnectionProfile {
59 pub fn new(connection_id: ConnectionId) -> Self {
60 let now = Utc::now();
61 Self {
62 connection_id,
63 fingerprint: SystemFingerprint::default(),
64 baseline: PerformanceBaseline::default(),
65 error_history: Vec::new(),
66 capabilities: HashMap::new(),
67 first_seen: now,
68 last_updated: now,
69 connection_count: 0,
70 }
71 }
72
73 pub fn record_latency(&mut self, latency_ms: f64) {
74 let b = &mut self.baseline;
75 let n = b.sample_count as f64;
76 b.avg_latency_ms = (b.avg_latency_ms * n + latency_ms) / (n + 1.0);
77 b.sample_count += 1;
78 b.last_measured = Some(Utc::now());
79 self.last_updated = Utc::now();
80 }
81
82 pub fn record_error(&mut self, error_type: &str, message: &str, status: Option<u16>) {
83 self.error_history.push(ErrorRecord {
84 timestamp: Utc::now(),
85 error_type: error_type.to_string(),
86 error_message: message.to_string(),
87 http_status: status,
88 resolved: false,
89 });
90 self.last_updated = Utc::now();
91 if self.error_history.len() > 100 {
93 self.error_history.drain(..self.error_history.len() - 100);
94 }
95 }
96}