agent-tk 0.4.0

`agent-tk` (`agent toolkit/tasks-knowledge`) is a crate for the development of autonomous agents using Rust, with an emphasis on tasks and knowledge based agents. This project is part of the [auKsys](http://auksys.org) project.
Documentation
use agent_tk::delegation::Task;
use futures::FutureExt;
use std::{sync::Arc, time::Duration};
use yaaral::prelude::*;

mod consts
{
  pub const MQTT_NODE_ID: &str = "org.auksys.agent-tk.delegation-server";
  pub const MQTT_HOSTNAME: &str = "localhost";
  pub const MQTT_PORT: u16 = 1883;
}

#[derive(serde::Deserialize)]
struct StartDelegationRequest
{
  task_type: String,
  task_description: String,
}

#[derive(serde::Serialize)]
struct StartDelegationAnswer
{
  success: bool,
  message: String,
}

struct TaskExecutor {}

impl agent_tk::execution::default::TaskExecutor for TaskExecutor
{
  fn execute_task(
    &self,
    _: agent_tk::definitions::task::Task,
  ) -> futures::future::BoxFuture<'static, agent_tk::Result<()>>
  {
    async { Ok(()) }.boxed()
  }
  fn can_execute(&self, _: &agent_tk::definitions::task::Task) -> bool
  {
    false
  }
}

fn main()
{
  let runtime =
    agent_tk::Runtime::new(agent_tk::yaaral::Config::new().prefix("agent-tk-delegation-server"))
      .expect("a runtime");
  let (mqtt_channel_client, mqtt_task) = mqtt_channel::Client::build(
    format!("{}-services", consts::MQTT_NODE_ID),
    consts::MQTT_HOSTNAME,
    consts::MQTT_PORT,
  )
  .start();
  runtime.spawn_tokio_task(mqtt_task).unwrap().detach();
  let mqtt_client = mqtt_service::Client::new(mqtt_channel_client.clone());

  let agent = agent_tk::Agent::new::<
    agent_tk::delegation::mqtt::Module,
    agent_tk::decision::default::Module,
    agent_tk::execution::default::Module,
  >(
    agent_tk::agent::AgentData {
      agent_uri: "agent-tk-delegation-server".to_string(),
      async_runtime: runtime.to_owned(),
      knowledge_base: Box::new(agent_tk::knowledge_base::InMemoryBase::new()),
      states: agent_tk::states::States::default().into(),
      capabilities: agent_tk::definitions::agent::capabilities::Capabilities::default(),
      projection: agent_tk::projection::Projection::new(0.0, 0.0),
    },
    agent_tk::delegation::mqtt::Options::new(mqtt_channel_client),
    agent_tk::decision::default::Options::new(),
    agent_tk::execution::default::Options::new(TaskExecutor {}),
  )
  .expect("to have successfully created an agent");

  let agent = Arc::new(agent);
  let mruntime = runtime.clone();
  runtime
    .spawn_task(mqtt_client.create_json_async_service(
      mruntime,
      "delegation_server/delegate",
      move |request: StartDelegationRequest| {
        let agent = agent.clone();
        async move {
          let f = async || {
            let task = agent_tk::definitions::task::Task::from_description(
              &request.task_type,
              &request.task_description,
            )?;
            println!("delegate_task");
            let result = agent.delegate_task(task).await;
            println!("result: {:?}", result);
            let result = match result
            {
              Ok(_) => StartDelegationAnswer {
                success: true,
                message: Default::default(),
              },
              Err(e) => StartDelegationAnswer {
                success: false,
                message: e.to_string(),
              },
            };
            Ok::<StartDelegationAnswer, agent_tk::Error>(result)
          };
          match f().await
          {
            Ok(r) => r,
            Err(e) => StartDelegationAnswer {
              success: false,
              message: format!("Failed to call service: {}", e),
            },
          }
        }
      },
      10,
    ))
    .expect("Service to be started.")
    .detach();

  loop
  {
    std::thread::sleep(Duration::from_secs(60 * 60 * 24));
  }
}