1use crate::types::error::LdpError;
7use async_trait::async_trait;
8use futures::Stream;
9use serde::{Deserialize, Serialize};
10use serde_json::Value;
11use std::pin::Pin;
12
13#[derive(Debug, Clone, Serialize, Deserialize)]
15pub struct RemoteSkill {
16 pub name: String,
18 pub description: Option<String>,
20 pub input_schema: Option<Value>,
22 pub output_schema: Option<Value>,
24}
25
26#[derive(Debug, Clone, Serialize, Deserialize)]
28pub struct RemoteCapabilities {
29 pub name: String,
31 pub description: Option<String>,
33 pub skills: Vec<RemoteSkill>,
35 pub protocols: Vec<String>,
37}
38
39#[derive(Debug, Clone, Serialize, Deserialize)]
41pub struct TaskRequest {
42 pub skill: String,
44 pub input: Value,
46}
47
48#[derive(Debug, Clone, Serialize, Deserialize)]
50pub struct TaskHandle {
51 pub task_id: String,
53 pub remote_url: String,
55}
56
57#[derive(Debug, Clone, Serialize, Deserialize)]
59pub enum TaskEvent {
60 Progress {
62 message: String,
63 progress: Option<f32>,
64 },
65 Completed { output: Value },
67 Failed { error: LdpError },
69}
70
71#[derive(Debug, Clone, Serialize, Deserialize)]
73pub enum TaskStatus {
74 Submitted,
76 Working,
78 Completed { output: Value },
80 Failed { error: LdpError },
82}
83
84pub type TaskStream = Pin<Box<dyn Stream<Item = TaskEvent> + Send>>;
86
87#[async_trait]
92pub trait ProtocolAdapter: Send + Sync {
93 async fn discover(&self, url: &str) -> Result<RemoteCapabilities, String>;
95
96 async fn invoke(&self, url: &str, task: TaskRequest) -> Result<TaskHandle, String>;
98
99 async fn stream(&self, url: &str, task: TaskRequest) -> Result<TaskStream, String>;
101
102 async fn status(&self, url: &str, task_id: &str) -> Result<TaskStatus, String>;
104
105 async fn cancel(&self, url: &str, task_id: &str) -> Result<(), String>;
107}
108
109pub struct ProtocolRegistry {
114 adapters: Vec<(String, std::sync::Arc<dyn ProtocolAdapter>, Vec<String>)>,
115}
116
117impl ProtocolRegistry {
118 pub fn new() -> Self {
120 Self {
121 adapters: Vec::new(),
122 }
123 }
124
125 pub fn register(
127 &mut self,
128 name: &str,
129 adapter: std::sync::Arc<dyn ProtocolAdapter>,
130 url_prefixes: Vec<&str>,
131 ) {
132 self.adapters.push((
133 name.to_string(),
134 adapter,
135 url_prefixes.iter().map(|s| s.to_string()).collect(),
136 ));
137 }
138
139 pub fn adapter(&self, name: &str) -> Option<&dyn ProtocolAdapter> {
141 self.adapters
142 .iter()
143 .find(|(n, _, _)| n == name)
144 .map(|(_, a, _)| a.as_ref())
145 }
146
147 pub fn adapter_for_url(&self, url: &str) -> Option<&dyn ProtocolAdapter> {
149 self.adapters
150 .iter()
151 .find(|(_, _, prefixes)| prefixes.iter().any(|p| url.starts_with(p)))
152 .map(|(_, a, _)| a.as_ref())
153 }
154
155 pub fn protocols(&self) -> Vec<&str> {
157 self.adapters.iter().map(|(n, _, _)| n.as_str()).collect()
158 }
159}
160
161impl Default for ProtocolRegistry {
162 fn default() -> Self {
163 Self::new()
164 }
165}