Skip to main content

ldp_protocol/types/
identity.rs

1//! LDP delegate identity card.
2//!
3//! Extends JamJet's `AgentCard` with AI-native identity fields:
4//! model family, weights fingerprint, reasoning profile, trust domain, etc.
5
6use crate::types::capability::LdpCapability;
7use crate::types::payload::PayloadMode;
8use crate::types::trust::TrustDomain;
9use serde::{Deserialize, Serialize};
10use std::collections::HashMap;
11
12/// Full LDP identity card for a delegate.
13///
14/// This is the rich typed representation maintained internally by the adapter.
15/// A subset of these fields is also written into `AgentCard.labels` with
16/// `ldp.*` keys for interoperability with JamJet's existing infrastructure.
17#[derive(Debug, Clone, Serialize, Deserialize)]
18pub struct LdpIdentityCard {
19    /// Unique delegate identifier (e.g. "ldp:delegate:challenger-alpha").
20    pub delegate_id: String,
21
22    /// Human-readable name.
23    pub name: String,
24
25    /// Optional description of the delegate's purpose.
26    pub description: Option<String>,
27
28    /// Model family (e.g. "Claude", "GPT", "Gemini").
29    pub model_family: String,
30
31    /// Model version (e.g. "2026.03").
32    pub model_version: String,
33
34    /// SHA-256 fingerprint of model weights, if available.
35    pub weights_fingerprint: Option<String>,
36
37    /// Trust domain this delegate belongs to.
38    pub trust_domain: TrustDomain,
39
40    /// Context window size in tokens.
41    pub context_window: u64,
42
43    /// Reasoning profile (e.g. "analytical", "creative", "adversarial-analytical").
44    pub reasoning_profile: Option<String>,
45
46    /// Cost profile (e.g. "low", "medium", "high").
47    pub cost_profile: Option<String>,
48
49    /// Latency profile (e.g. "p50:2000ms", "p99:8000ms").
50    pub latency_profile: Option<String>,
51
52    /// Jurisdictional constraints (e.g. "us-east", "eu-west").
53    pub jurisdiction: Option<String>,
54
55    /// Capabilities this delegate offers.
56    pub capabilities: Vec<LdpCapability>,
57
58    /// Supported payload modes, ordered by preference.
59    pub supported_payload_modes: Vec<PayloadMode>,
60
61    /// Endpoint URL for the delegate.
62    pub endpoint: String,
63
64    /// Additional metadata.
65    #[serde(default)]
66    pub metadata: HashMap<String, String>,
67}
68
69impl LdpIdentityCard {
70    /// Convert identity fields into `AgentCard.labels` entries.
71    ///
72    /// Keys are prefixed with `ldp.` to avoid collisions with other protocols.
73    pub fn to_labels(&self) -> HashMap<String, String> {
74        let mut labels = HashMap::new();
75        labels.insert("ldp.delegate_id".into(), self.delegate_id.clone());
76        labels.insert("ldp.model_family".into(), self.model_family.clone());
77        labels.insert("ldp.model_version".into(), self.model_version.clone());
78        labels.insert("ldp.trust_domain".into(), self.trust_domain.name.clone());
79        labels.insert("ldp.context_window".into(), self.context_window.to_string());
80
81        if let Some(ref fp) = self.weights_fingerprint {
82            labels.insert("ldp.weights_fingerprint".into(), fp.clone());
83        }
84        if let Some(ref rp) = self.reasoning_profile {
85            labels.insert("ldp.reasoning_profile".into(), rp.clone());
86        }
87        if let Some(ref cp) = self.cost_profile {
88            labels.insert("ldp.cost_profile".into(), cp.clone());
89        }
90        if let Some(ref lp) = self.latency_profile {
91            labels.insert("ldp.latency_profile".into(), lp.clone());
92        }
93        if let Some(ref j) = self.jurisdiction {
94            labels.insert("ldp.jurisdiction".into(), j.clone());
95        }
96
97        // Payload modes as comma-separated list.
98        let modes: Vec<String> = self
99            .supported_payload_modes
100            .iter()
101            .map(|m| m.to_string())
102            .collect();
103        labels.insert("ldp.payload_modes".into(), modes.join(","));
104
105        labels
106    }
107}