1use crate::types::contract::DelegationContract;
7use crate::types::error::LdpError;
8use async_trait::async_trait;
9use futures::Stream;
10use serde::{Deserialize, Serialize};
11use serde_json::Value;
12use std::pin::Pin;
13
14#[derive(Debug, Clone, Serialize, Deserialize)]
16pub struct RemoteSkill {
17 pub name: String,
19 pub description: Option<String>,
21 pub input_schema: Option<Value>,
23 pub output_schema: Option<Value>,
25}
26
27#[derive(Debug, Clone, Serialize, Deserialize)]
29pub struct RemoteCapabilities {
30 pub name: String,
32 pub description: Option<String>,
34 pub skills: Vec<RemoteSkill>,
36 pub protocols: Vec<String>,
38}
39
40#[derive(Debug, Clone, Serialize, Deserialize)]
42pub struct TaskRequest {
43 pub skill: String,
45 pub input: Value,
47 #[serde(skip_serializing_if = "Option::is_none", default)]
49 pub contract: Option<DelegationContract>,
50}
51
52#[derive(Debug, Clone, Serialize, Deserialize)]
54pub struct TaskHandle {
55 pub task_id: String,
57 pub remote_url: String,
59}
60
61#[derive(Debug, Clone, Serialize, Deserialize)]
63pub enum TaskEvent {
64 Progress {
66 message: String,
67 progress: Option<f32>,
68 },
69 Completed { output: Value },
71 Failed { error: LdpError },
73}
74
75#[derive(Debug, Clone, Serialize, Deserialize)]
77pub enum TaskStatus {
78 Submitted,
80 Working,
82 Completed { output: Value },
84 Failed { error: LdpError },
86}
87
88pub type TaskStream = Pin<Box<dyn Stream<Item = TaskEvent> + Send>>;
90
91#[async_trait]
96pub trait ProtocolAdapter: Send + Sync {
97 async fn discover(&self, url: &str) -> Result<RemoteCapabilities, String>;
99
100 async fn invoke(&self, url: &str, task: TaskRequest) -> Result<TaskHandle, String>;
102
103 async fn stream(&self, url: &str, task: TaskRequest) -> Result<TaskStream, String>;
105
106 async fn status(&self, url: &str, task_id: &str) -> Result<TaskStatus, String>;
108
109 async fn cancel(&self, url: &str, task_id: &str) -> Result<(), String>;
111}
112
113pub struct ProtocolRegistry {
118 adapters: Vec<(String, std::sync::Arc<dyn ProtocolAdapter>, Vec<String>)>,
119}
120
121impl ProtocolRegistry {
122 pub fn new() -> Self {
124 Self {
125 adapters: Vec::new(),
126 }
127 }
128
129 pub fn register(
131 &mut self,
132 name: &str,
133 adapter: std::sync::Arc<dyn ProtocolAdapter>,
134 url_prefixes: Vec<&str>,
135 ) {
136 self.adapters.push((
137 name.to_string(),
138 adapter,
139 url_prefixes.iter().map(|s| s.to_string()).collect(),
140 ));
141 }
142
143 pub fn adapter(&self, name: &str) -> Option<&dyn ProtocolAdapter> {
145 self.adapters
146 .iter()
147 .find(|(n, _, _)| n == name)
148 .map(|(_, a, _)| a.as_ref())
149 }
150
151 pub fn adapter_for_url(&self, url: &str) -> Option<&dyn ProtocolAdapter> {
153 self.adapters
154 .iter()
155 .find(|(_, _, prefixes)| prefixes.iter().any(|p| url.starts_with(p)))
156 .map(|(_, a, _)| a.as_ref())
157 }
158
159 pub fn protocols(&self) -> Vec<&str> {
161 self.adapters.iter().map(|(n, _, _)| n.as_str()).collect()
162 }
163}
164
165impl Default for ProtocolRegistry {
166 fn default() -> Self {
167 Self::new()
168 }
169}