agent_tk/
agent.rs

1//! This module defines an tk agent.
2
3use log::info;
4use yaaral::TaskInterface as _;
5
6use crate::prelude::*;
7
8use delegation::Task;
9use module::Module;
10
11//     _                    _   ____        _
12//    / \   __ _  ___ _ __ | |_|  _ \  __ _| |_ __ _
13//   / _ \ / _` |/ _ \ '_ \| __| | | |/ _` | __/ _` |
14//  / ___ | (_| |  __/ | | | |_| |_| | (_| | || (_| |
15// /_/   \_\__, |\___|_| |_|\__|____/ \__,_|\__\__,_|
16//         |___/
17
18/// Data of an agent
19#[derive(Clone)]
20pub struct AgentData
21{
22  /// Uri of the agent
23  pub agent_uri: String,
24  /// Runtime for async (selected as a feature)
25  pub async_runtime: crate::Runtime,
26  /// Interface to the knowledge base of the agent
27  pub knowledge_base: Box<dyn knowledge_base::KnowledgeBase>,
28  /// Internal copy of the states of the agent
29  pub states: states::SharedStates,
30  /// Capabilities of the agent
31  pub capabilities: definitions::agent::capabilities::Capabilities,
32  /// Geographic projection
33  pub projection: projection::Projection,
34}
35
36ccutils::assert_impl_all!(AgentData: Sync, Send);
37
38//                           _
39//     /\                   | |
40//    /  \   __ _  ___ _ __ | |_
41//   / /\ \ / _` |/ _ \ '_ \| __|
42//  / ____ \ (_| |  __/ | | | |_
43// /_/    \_\__, |\___|_| |_|\__|
44//           __/ |
45//          |___/
46
47/// This class represent a TK agent
48pub struct Agent
49{
50  agent_data: AgentData,
51  delegation_interface:
52    module::ModuleInterface<delegation::InputMessage, delegation::OutputMessage>,
53}
54
55impl Agent
56{
57  /// Create a new agent with the given knowlege base and transport for the delegation
58  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    // transport_interface.input_sender().
80
81    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  /// Return a reference to the projection used by this agent
127  pub fn projection_ref(&self) -> &crate::projection::Projection
128  {
129    &self.agent_data.projection
130  }
131  /// Return a reference to the states of this agent
132  pub fn states_ref(&self) -> &crate::states::SharedStates
133  {
134    &self.agent_data.states
135  }
136  /// Return a reference to the capabilities of this agent
137  pub fn capabilities_ref(&self) -> &definitions::agent::capabilities::Capabilities
138  {
139    &self.agent_data.capabilities
140  }
141  /// Start the delegation of a task by this agent
142  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}