From e5469a6a5d1806db611b7f1b1e13f721abb74b71 Mon Sep 17 00:00:00 2001 From: FyS Date: Fri, 17 Nov 2023 10:41:45 +0100 Subject: [PATCH] update Agent communication protocol --- fabko/CMakeLists.txt | 8 +- fabko/agent/action.hh | 41 ++++++ fabko/agent/agent.cpp | 19 +++ fabko/agent/agent.hh | 28 ++++ fabko/core/acl.hh | 2 +- fabko/core/blackboard.cpp | 14 +- fabko/core/blackboard.hh | 16 +-- fabko/core/common/string_utils.hh | 4 +- fabko/core/protocol/boardcom.cpp | 33 +++++ fabko/core/protocol/boardcom.hh | 70 ++++++++++ fabko/core/protocol/fap_request.hh | 60 +++++++++ tests/core/common/test_algo_utils.cpp | 184 +++++++++++++------------- 12 files changed, 366 insertions(+), 113 deletions(-) create mode 100755 fabko/agent/action.hh create mode 100755 fabko/core/protocol/boardcom.cpp create mode 100755 fabko/core/protocol/boardcom.hh create mode 100755 fabko/core/protocol/fap_request.hh diff --git a/fabko/CMakeLists.txt b/fabko/CMakeLists.txt index ec4d4fb..4404b77 100644 --- a/fabko/CMakeLists.txt +++ b/fabko/CMakeLists.txt @@ -8,9 +8,10 @@ target_sources(core PUBLIC core/blackboard.cpp core/blackboard.hh - core/boardcom.cpp - core/boardcom.hh core/acl.hh + core/protocol/fap_request.hh + core/protocol/boardcom.cpp + core/protocol/boardcom.hh core/common/logging.cpp core/common/logging.hh core/common/exception.hh @@ -49,13 +50,14 @@ add_library(agent OBJECT) target_sources(agent PRIVATE agent/agent.cpp + agent/action.hh PUBLIC agent/agent.hh) target_include_directories(agent PUBLIC agent ) -target_link_libraries(agent PRIVATE fabko::core) target_compile_definitions(agent PUBLIC cxx_std_23) +target_link_libraries(agent PRIVATE fabko::core) add_library(fabko::agent ALIAS agent) diff --git a/fabko/agent/action.hh b/fabko/agent/action.hh new file mode 100755 index 0000000..90f55a3 --- /dev/null +++ b/fabko/agent/action.hh @@ -0,0 +1,41 @@ +// Dual Licensing Either : +// - AGPL +// or +// - Subscription license for commercial usage (without requirement of licensing propagation). +// please contact ballandfys@protonmail.com for additional information about this subscription commercial licensing. +// +// Created by FyS on 13/11/2023. License 2022-2023 +// +// In the case no license has been purchased for the use (modification or distribution in any way) of the software stack +// the APGL license is applying. +// + +#pragma once + +#include + +#include + +namespace fabko { + +enum class action_source { + automatic, + manual +}; + +/** + * Represent an action that an agent is doing / going to do. + * This is + */ +struct agent_action { + + unsigned action_id{}; + + action_source source{action_source::automatic}; + + agent_protocol::request initial_request; + + agent_protocol::status status; +}; + +} // namespace fabko \ No newline at end of file diff --git a/fabko/agent/agent.cpp b/fabko/agent/agent.cpp index a4b1846..f453932 100644 --- a/fabko/agent/agent.cpp +++ b/fabko/agent/agent.cpp @@ -9,7 +9,26 @@ // In the case no license has been purchased for the use (modification or distribution in any way) of the software stack // the APGL license is applying. // + +#include + #include "agent.hh" +#include "protocol/fap_request.hh" + namespace fabko { + +constexpr std::size_t MAX_QUEUED_SIZE = 10; + +//! implementation details of the agent +struct impl { + + + /** + * list of actions that the agent is going to do. The list is ordered by priority + */ + std::array action_list; // implementation as a ring buffer may prove beneficial + +}; + } \ No newline at end of file diff --git a/fabko/agent/agent.hh b/fabko/agent/agent.hh index dd6918e..2475912 100644 --- a/fabko/agent/agent.hh +++ b/fabko/agent/agent.hh @@ -12,9 +12,37 @@ #pragma once +#include +#include +#include + namespace fabko { +template class agent { + struct impl; + + public: + ~agent() = default; + + // extract requirement of the type on a static assertion as agent symbol is not available to the compiler at the + // template declaration level. + static_assert( + std::is_invocable_v, + "The action function provided to the agent has to be with the following signature: void(agent&)"); + + + [[nodiscard]] std::expected<> + + private: + void execute_action() { + _callback_on_action(*this); + } + + action _callback_on_action; + + std::unique_ptr _pimpl; + }; } // namespace fabko \ No newline at end of file diff --git a/fabko/core/acl.hh b/fabko/core/acl.hh index d4bc016..a86d57a 100644 --- a/fabko/core/acl.hh +++ b/fabko/core/acl.hh @@ -96,7 +96,7 @@ constexpr bool is_error_handling(message_type type) { } struct acc { - unsigned identifier; + unsigned identifier{}; // communication protocol : which can be used in other to define different ways to communicate between the agents std::string protocol; diff --git a/fabko/core/blackboard.cpp b/fabko/core/blackboard.cpp index 014a10b..42a6f41 100644 --- a/fabko/core/blackboard.cpp +++ b/fabko/core/blackboard.cpp @@ -18,31 +18,31 @@ namespace fabko { struct blackboard::blackboard_impl { - explicit blackboard_impl(com::c_board_com auto&& bc, blackboard_data data) + explicit blackboard_impl(agent_protocol::c_board_com auto&& bc, blackboard_data data) : bc(std::forward(bc)), data(std::move(data)) {} blackboard_data instantiate_black_board(const std::string& request) { - data.id = std::visit( + std::visit( overloaded{[&request](auto& b) -> std::string { return b.instantiate_black_board(request); }}, bc); return data; } - com::board_protocol bc; + agent_protocol::board_protocol bc; blackboard_data data; }; blackboard::~blackboard() = default; -template -blackboard::blackboard(BoardCommunication&& bc, com::request initial_request) +template +blackboard::blackboard(BoardCommunication&& bc, agent_protocol::request initial_request) : _pimpl(std::forward(bc), {.initial_request = std::move(initial_request)}) { } -com::propositions blackboard::request_propositions(const com::request& request) { +agent_protocol::propositions blackboard::request_propositions(const agent_protocol::request& request) { return {}; } -com::decision_status blackboard::submit_decision(const std::string& decision) { +agent_protocol::decision_status blackboard::submit_decision(const std::string& decision) { return {}; } diff --git a/fabko/core/blackboard.hh b/fabko/core/blackboard.hh index 994aa60..a836fb2 100644 --- a/fabko/core/blackboard.hh +++ b/fabko/core/blackboard.hh @@ -18,14 +18,14 @@ #include #include -#include "boardcom.hh" +#include "protocol/boardcom.hh" +#include "protocol/fap_request.hh" namespace fabko { struct blackboard_data { - std::string id{}; - com::request initial_request; - com::propositions propositions{}; + agent_protocol::request initial_request; + agent_protocol::propositions propositions{}; }; /** @@ -40,11 +40,11 @@ class blackboard { public: ~blackboard(); - template - explicit blackboard(BoardCommunication&& bc, com::request initial_request); + template + explicit blackboard(BoardCommunication&& bc, agent_protocol::request initial_request); - [[nodiscard]] com::propositions request_propositions(const com::request& request); - [[nodiscard]] com::decision_status submit_decision(const std::string& decision); + [[nodiscard]] agent_protocol::propositions request_propositions(const agent_protocol::request& request); + [[nodiscard]] agent_protocol::decision_status submit_decision(const std::string& decision); private: std::unique_ptr _pimpl; diff --git a/fabko/core/common/string_utils.hh b/fabko/core/common/string_utils.hh index 16faa75..8083aa5 100644 --- a/fabko/core/common/string_utils.hh +++ b/fabko/core/common/string_utils.hh @@ -20,7 +20,7 @@ namespace fabko { template -void split_string(const std::string& input, const std::string& separator, Handler&& handler, int limitation = -1) { +void split_string(std::string_view input, std::string_view separator, Handler&& handler, int limitation = -1) { std::size_t pos_start = 0; std::size_t pos_end; @@ -37,7 +37,7 @@ void split_string(const std::string& input, const std::string& separator, Handle } template -void split_string(const std::string& input, const std::vector& separators, Handler&& handler, int limitation = -1) { +void split_string(std::string_view input, const std::vector& separators, Handler&& handler, int limitation = -1) { std::size_t pos_start = 0; std::size_t pos_end; diff --git a/fabko/core/protocol/boardcom.cpp b/fabko/core/protocol/boardcom.cpp new file mode 100755 index 0000000..6a9b26e --- /dev/null +++ b/fabko/core/protocol/boardcom.cpp @@ -0,0 +1,33 @@ +// Dual Licensing Either : +// - AGPL +// or +// - Subscription license for commercial usage (without requirement of licensing propagation). +// please contact ballandfys@protonmail.com for additional information about this subscription commercial licensing. +// +// Created by FyS on 23/04/23. License 2022-2023 +// +// In the case no license has been purchased for the use (modification or distribution in any way) of the software stack +// the APGL license is applying. +// + +#include "boardcom.hh" + +namespace fabko { + +std::string agent_protocol::p2p::instantiate_black_board(const std::string&) { + return {}; +} + +std::string agent_protocol::online::instantiate_black_board(const std::string&) { + return {}; +} + +std::future agent_protocol::online::request_propositions(const std::string&) { + return {}; +} + +agent_protocol::decision_status agent_protocol::online::commit_decision(const std::string&) { + return agent_protocol::decision_status::RETRY; +} + +} // namespace fabko diff --git a/fabko/core/protocol/boardcom.hh b/fabko/core/protocol/boardcom.hh new file mode 100755 index 0000000..98672c8 --- /dev/null +++ b/fabko/core/protocol/boardcom.hh @@ -0,0 +1,70 @@ +// Dual Licensing Either : +// - AGPL +// or +// - Subscription license for commercial usage (without requirement of licensing propagation). +// please contact ballandfys@protonmail.com for additional information about this subscription commercial licensing. +// +// Created by FyS on 23/04/23. License 2022-2023 +// +// In the case no license has been purchased for the use (modification or distribution in any way) of the software stack +// the APGL license is applying. +// + +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "fap_request.hh" + +namespace fabko::agent_protocol { + +struct proposition { + std::string id; +}; + +struct propositions { + std::optional> props; + status status{status::awaiting}; +}; + +enum class decision_status { + SUCCESS, + RETRY, + CANCELLED, +}; + + +/** + * + * @tparam T + */ +template +concept c_board_com = + requires(T a) { + { T::make_board(request{}) } -> std::convertible_to; + { a.propositions(std::string{}) } -> std::convertible_to>; + { a.commit_decision(std::string{}) } -> std::convertible_to; + } && std::movable; + +class p2p { +public: + static std::string instantiate_black_board(const std::string&); + std::future request_propositions(const std::string&); + decision_status commit_decision(const std::string&); +}; + +class online { +public: + static std::string instantiate_black_board(const std::string&); + std::future request_propositions(const std::string&); + decision_status commit_decision(const std::string&); +}; + +using board_protocol = std::variant; + +} // namespace fabko::com diff --git a/fabko/core/protocol/fap_request.hh b/fabko/core/protocol/fap_request.hh new file mode 100755 index 0000000..63122f0 --- /dev/null +++ b/fabko/core/protocol/fap_request.hh @@ -0,0 +1,60 @@ +// Dual Licensing Either : +// - AGPL +// or +// - Subscription license for commercial usage (without requirement of licensing propagation). +// please contact ballandfys@protonmail.com for additional information about this subscription commercial licensing. +// +// Created by FyS on 13/11/2023. License 2022-2023 +// +// In the case no license has been purchased for the use (modification or distribution in any way) of the software stack +// the APGL license is applying. +// + +#pragma once + +#include +#include +#include + +namespace fabko::agent_protocol { + +struct lesser_than {}; +struct greater_than {}; +struct greater_or_eq {}; +struct lesser_or_eq {}; +struct eq {}; + +//! all possible comparator +using comparator = std::variant; + +enum class status : char { + awaiting = 0, + on_going = 1, + done = 2, + wont_do = 3, + cancel = 4 +}; + +struct resource { + std::string resource; + + auto operator<=>(const struct resource&) const = default; +}; + +//! option are filters that can restrict a specific request, the importance weight on the comparison importance +struct option { + resource resource_id; + unsigned importance{}; + comparator cmp; +}; + +struct request { + std::string emitter; + std::string request; + + // this vector is ordered by importance before usage in order to ensure that the most valuable filter is first in the list + // of responses. + std::vector