use log::info;
use yaaral::TaskInterface as _;
use crate::prelude::*;
use delegation::Task;
use module::Module;
#[derive(Clone)]
pub struct AgentData
{
pub agent_uri: String,
pub async_runtime: crate::Runtime,
pub knowledge_base: Box<dyn knowledge_base::KnowledgeBase>,
pub states: states::SharedStates,
pub capabilities: definitions::agent::capabilities::Capabilities,
pub projection: projection::Projection,
}
ccutils::assert_impl_all!(AgentData: Sync, Send);
pub struct Agent
{
agent_data: AgentData,
delegation_interface:
module::ModuleInterface<delegation::InputMessage, delegation::OutputMessage>,
}
impl Agent
{
pub fn new<TTransport, TDecision, TExecution>(
agent_data: AgentData,
transport_options: TTransport::Options,
decision_options: TDecision::Options,
executor_options: TExecution::Options,
) -> Result<Self>
where
TTransport: delegation::transport::Module,
TDecision: decision::Module,
TExecution: execution::Module,
{
let transport_interfaces = TTransport::prepare_interfaces(200);
let delegation_interfaces = delegation::Module::prepare_interfaces(200);
let decision_interfaces = TDecision::prepare_interfaces(200);
let executor_interfaces = TExecution::prepare_interfaces(200);
let transport_interface = transport_interfaces.0.clone();
let execution_interface = executor_interfaces.0.clone();
let delegation_interface = delegation_interfaces.0.clone();
let decision_interface = decision_interfaces.0.clone();
let transport_module = TTransport::start(
agent_data.to_owned(),
transport_interfaces,
delegation_interfaces.0.clone(),
transport_options,
)?;
let delegation_module = delegation::Module::start(
agent_data.to_owned(),
delegation_interfaces,
transport_interface,
decision_interface,
);
let decision_module = TDecision::start(
agent_data.to_owned(),
decision_interfaces,
execution_interface,
decision_options,
);
let execution_module =
TExecution::start(agent_data.to_owned(), executor_interfaces, executor_options);
agent_data
.async_runtime
.spawn_task(transport_module)
.map_spawn_error()?
.detach();
agent_data
.async_runtime
.spawn_task(delegation_module)
.map_spawn_error()?
.detach();
agent_data
.async_runtime
.spawn_task(decision_module)
.map_spawn_error()?
.detach();
agent_data
.async_runtime
.spawn_task(execution_module)
.map_spawn_error()?
.detach();
Ok(Self {
agent_data,
delegation_interface,
})
}
pub fn projection_ref(&self) -> &crate::projection::Projection
{
&self.agent_data.projection
}
pub fn states_ref(&self) -> &crate::states::SharedStates
{
&self.agent_data.states
}
pub fn capabilities_ref(&self) -> &definitions::agent::capabilities::Capabilities
{
&self.agent_data.capabilities
}
pub fn delegate_task<'b>(
&self,
task: definitions::task::Task,
) -> impl std::future::Future<Output = Result<()>> + 'b
{
log::info!("Start delegation of task {:?}", task.task_id());
let agent_data = self.agent_data.clone();
let delegation_input_sender = self.delegation_interface.input_sender();
let mut delegation_output_recv = self.delegation_interface.output_receiver();
async move {
let task_uuid = task.task_id();
delegation_input_sender
.broadcast(delegation::InputMessage::create_start_delegation(
agent_data.agent_uri.to_owned(),
task,
None,
))
.await?;
while let Ok(msg) = delegation_output_recv.recv().await
{
match msg
{
delegation::OutputMessage::Status { uuid, status } =>
{
if uuid == task_uuid
{
info!("Delegation {:?} received status {:?}", uuid, status);
}
}
}
}
Ok(())
}
}
}