Skip to main content

ldp_protocol/types/
capability.rs

1//! LDP capability manifest types.
2//!
3//! Each delegate advertises capabilities with associated quality, latency,
4//! and cost metadata — richer than A2A/MCP skill listings.
5
6use serde::{Deserialize, Serialize};
7use serde_json::Value;
8
9/// How a quality claim was established — addresses the provenance paradox.
10#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
11#[serde(rename_all = "snake_case")]
12pub enum ClaimType {
13    /// Quality scores reported by the delegate itself.
14    #[default]
15    SelfClaimed,
16    /// Quality scores attested by a trusted third-party issuer.
17    IssuerAttested,
18    /// Quality scores measured by the LDP runtime during actual invocations.
19    RuntimeObserved,
20    /// Quality scores verified by an external benchmarking service.
21    ExternallyBenchmarked,
22}
23
24/// An LDP capability — a skill with quality/latency/cost metadata.
25#[derive(Debug, Clone, Serialize, Deserialize)]
26pub struct LdpCapability {
27    /// Capability name (e.g. "code-review", "mathematical-reasoning").
28    pub name: String,
29
30    /// Human-readable description.
31    pub description: Option<String>,
32
33    /// Input schema (JSON Schema).
34    pub input_schema: Option<Value>,
35
36    /// Output schema (JSON Schema).
37    pub output_schema: Option<Value>,
38
39    /// Quality and performance metrics for this capability.
40    pub quality: Option<QualityMetrics>,
41
42    /// Domains this capability applies to (e.g. ["rust", "python"]).
43    #[serde(default)]
44    pub domains: Vec<String>,
45}
46
47/// Quality, latency, and cost metrics for a capability.
48///
49/// These metrics enable intelligent routing: the JamJet workflow engine
50/// can select among multiple delegates based on quality-cost tradeoffs.
51#[derive(Debug, Clone, Default, Serialize, Deserialize)]
52pub struct QualityMetrics {
53    /// Self-reported quality score (0.0 – 1.0).
54    pub quality_score: Option<f64>,
55
56    /// Expected latency in milliseconds (p50).
57    pub latency_p50_ms: Option<u64>,
58
59    /// Expected latency in milliseconds (p99).
60    pub latency_p99_ms: Option<u64>,
61
62    /// Cost per invocation in USD (approximate).
63    pub cost_per_call_usd: Option<f64>,
64
65    /// Maximum tokens this capability can process per call.
66    pub max_tokens: Option<u64>,
67
68    /// Whether this capability supports streaming responses.
69    pub supports_streaming: bool,
70
71    /// How this quality claim was established.
72    #[serde(default)]
73    pub claim_type: ClaimType,
74}
75
76#[cfg(test)]
77mod tests {
78    use super::*;
79
80    #[test]
81    fn default_claim_type_is_self_claimed() {
82        let metrics = QualityMetrics::default();
83        assert_eq!(metrics.claim_type, ClaimType::SelfClaimed);
84    }
85
86    #[test]
87    fn claim_type_serialization() {
88        let metrics = QualityMetrics {
89            claim_type: ClaimType::IssuerAttested,
90            quality_score: Some(0.95),
91            ..Default::default()
92        };
93        let json = serde_json::to_value(&metrics).unwrap();
94        assert_eq!(json["claim_type"], "issuer_attested");
95        let restored: QualityMetrics = serde_json::from_value(json).unwrap();
96        assert_eq!(restored.claim_type, ClaimType::IssuerAttested);
97    }
98
99    #[test]
100    fn all_claim_types_exist() {
101        let _ = ClaimType::SelfClaimed;
102        let _ = ClaimType::IssuerAttested;
103        let _ = ClaimType::RuntimeObserved;
104        let _ = ClaimType::ExternallyBenchmarked;
105    }
106}