1use log::info;
4use yaaral::TaskInterface as _;
5
6use crate::prelude::*;
7
8use delegation::Task;
9use module::Module;
10
11#[derive(Clone)]
20pub struct AgentData
21{
22 pub agent_uri: String,
24 pub async_runtime: crate::Runtime,
26 pub knowledge_base: Box<dyn knowledge_base::KnowledgeBase>,
28 pub states: states::SharedStates,
30 pub capabilities: definitions::agent::capabilities::Capabilities,
32 pub projection: projection::Projection,
34}
35
36ccutils::assert_impl_all!(AgentData: Sync, Send);
37
38pub struct Agent
49{
50 agent_data: AgentData,
51 delegation_interface:
52 module::ModuleInterface<delegation::InputMessage, delegation::OutputMessage>,
53}
54
55impl Agent
56{
57 pub fn new<TTransport, TDecision, TExecution>(
59 agent_data: AgentData,
60 transport_options: TTransport::Options,
61 decision_options: TDecision::Options,
62 executor_options: TExecution::Options,
63 ) -> Result<Self>
64 where
65 TTransport: delegation::transport::Module,
66 TDecision: decision::Module,
67 TExecution: execution::Module,
68 {
69 let transport_interfaces = TTransport::prepare_interfaces(200);
70 let delegation_interfaces = delegation::Module::prepare_interfaces(200);
71 let decision_interfaces = TDecision::prepare_interfaces(200);
72 let executor_interfaces = TExecution::prepare_interfaces(200);
73
74 let transport_interface = transport_interfaces.0.clone();
75 let execution_interface = executor_interfaces.0.clone();
76 let delegation_interface = delegation_interfaces.0.clone();
77 let decision_interface = decision_interfaces.0.clone();
78
79 let transport_module = TTransport::start(
82 agent_data.to_owned(),
83 transport_interfaces,
84 delegation_interfaces.0.clone(),
85 transport_options,
86 )?;
87 let delegation_module = delegation::Module::start(
88 agent_data.to_owned(),
89 delegation_interfaces,
90 transport_interface,
91 decision_interface,
92 );
93 let decision_module = TDecision::start(
94 agent_data.to_owned(),
95 decision_interfaces,
96 execution_interface,
97 decision_options,
98 );
99 let execution_module =
100 TExecution::start(agent_data.to_owned(), executor_interfaces, executor_options);
101 agent_data
102 .async_runtime
103 .spawn_task(transport_module)
104 .map_spawn_error()?
105 .detach();
106 agent_data
107 .async_runtime
108 .spawn_task(delegation_module)
109 .map_spawn_error()?
110 .detach();
111 agent_data
112 .async_runtime
113 .spawn_task(decision_module)
114 .map_spawn_error()?
115 .detach();
116 agent_data
117 .async_runtime
118 .spawn_task(execution_module)
119 .map_spawn_error()?
120 .detach();
121 Ok(Self {
122 agent_data,
123 delegation_interface,
124 })
125 }
126 pub fn projection_ref(&self) -> &crate::projection::Projection
128 {
129 &self.agent_data.projection
130 }
131 pub fn states_ref(&self) -> &crate::states::SharedStates
133 {
134 &self.agent_data.states
135 }
136 pub fn capabilities_ref(&self) -> &definitions::agent::capabilities::Capabilities
138 {
139 &self.agent_data.capabilities
140 }
141 pub fn delegate_task<'b>(
143 &self,
144 task: definitions::task::Task,
145 ) -> impl std::future::Future<Output = Result<()>> + 'b
146 {
147 log::info!("Start delegation of task {:?}", task.task_id());
148 let agent_data = self.agent_data.clone();
149 let delegation_input_sender = self.delegation_interface.input_sender();
150 let mut delegation_output_recv = self.delegation_interface.output_receiver();
151 async move {
152 let task_uuid = task.task_id();
153 delegation_input_sender
154 .broadcast(delegation::InputMessage::create_start_delegation(
155 agent_data.agent_uri.to_owned(),
156 task,
157 None,
158 ))
159 .await?;
160 while let Ok(msg) = delegation_output_recv.recv().await
161 {
162 match msg
163 {
164 delegation::OutputMessage::Status { uuid, status } =>
165 {
166 if uuid == task_uuid
167 {
168 info!("Delegation {:?} received status {:?}", uuid, status);
169 }
170 }
171 }
172 }
173 Ok(())
174 }
175 }
176}