diff --git a/morpheus/_lib/include/morpheus/llm/llm_context.hpp b/morpheus/_lib/include/morpheus/llm/llm_context.hpp index 03956c50fe..2e4d7cfcc6 100644 --- a/morpheus/_lib/include/morpheus/llm/llm_context.hpp +++ b/morpheus/_lib/include/morpheus/llm/llm_context.hpp @@ -39,45 +39,149 @@ struct LLMContextState nlohmann::json values; }; +/** + * @brief Holds and manages information related to LLM tasks and input mappings required for LLMNode execution. + * + */ class MORPHEUS_EXPORT LLMContext : public std::enable_shared_from_this { public: + /** + * @brief Construct a new LLMContext object. + * + */ LLMContext(); + /** + * @brief Construct a new LLMContext object. + * + * @param task task for new context + * @param message control message for new context + */ LLMContext(LLMTask task, std::shared_ptr message); + /** + * @brief Construct a new LLMContext object. + * + * @param parent parent context + * @param name new context name + * @param inputs input mappings for new context + */ LLMContext(std::shared_ptr parent, std::string name, input_mappings_t inputs); + /** + * @brief Destroy the LLMContext object. + * + */ ~LLMContext(); + /** + * @brief Get parent context. + * + * @return std::shared_ptr + */ std::shared_ptr parent() const; + /** + * @brief Get name of context. + * + * @return const std::string& + */ const std::string& name() const; + /** + * @brief Get map of internal mappings for this context. + * + * @return const input_mappings_t& + */ const input_mappings_t& input_map() const; + /** + * @brief Get task for this context. + * + * @return const LLMTask& + */ const LLMTask& task() const; + /** + * @brief Get control message for this context. + * + * @return std::shared_ptr& + */ std::shared_ptr& message() const; + /** + * @brief Get all output mappings for this context. + * + * @return nlohmann::json::const_reference + */ nlohmann::json::const_reference all_outputs() const; + /** + * @brief Get full name of context containing parents up to root. + * + * @return std::string + */ std::string full_name() const; + /** + * @brief Create new context from this context with provided name and input mappings. + * + * @param name name of new context + * @param inputs input mappings for new context + * @return std::shared_ptr + */ std::shared_ptr push(std::string name, input_mappings_t inputs); + /** + * @brief Moves output map from this context to parent context. Outputs to move can be selected using + * set_output_names, otherwise all outputs are noved by default. + * + */ void pop(); + /** + * @brief Get the input value from parent context corresponding to first internal input of this context. + * + * @return nlohmann::json::const_reference + */ nlohmann::json::const_reference get_input() const; + /** + * @brief Get the parent output value corresponding to given internal input name. + * + * @param node_name internal input name + * @return nlohmann::json::const_reference + */ nlohmann::json::const_reference get_input(const std::string& node_name) const; + /** + * @brief Get parent output values corresponding to all internal input names. + * + * @return nlohmann::json + */ nlohmann::json get_inputs() const; + /** + * @brief Set output mappings for this context. + * + * @param outputs output mappings + */ void set_output(nlohmann::json outputs); + /** + * @brief Set an output value for this context. + * + * @param output_name output name + * @param output output value + */ void set_output(const std::string& output_name, nlohmann::json output); + /** + * @brief Set the output names to propagate from this context when using pop. + * + * @param output_names output names to propagate + */ void set_output_names(std::vector output_names); void outputs_complete(); diff --git a/morpheus/_lib/include/morpheus/llm/llm_engine.hpp b/morpheus/_lib/include/morpheus/llm/llm_engine.hpp index 80f95a79f5..75021a753c 100644 --- a/morpheus/_lib/include/morpheus/llm/llm_engine.hpp +++ b/morpheus/_lib/include/morpheus/llm/llm_engine.hpp @@ -31,14 +31,43 @@ namespace morpheus::llm { +/** + * @brief A subclass of LLMNode that acts as container for components required in processing LLM service + * requests. For example, a prompt generator and LLM service can each be implemented as an LLMNode and added to + * the engine. Input mappings are used to match node's input to outputs of parent of sibling nodes. Task handlers + * can also be added to the engine to process the outputs of an LLM service to feed back to prompt generator, for + * example, or exit the engine. + */ class MORPHEUS_EXPORT LLMEngine : public LLMNode { public: + /** + * @brief Construct a new LLMEngine object. + * + */ LLMEngine(); + + /** + * @brief Destroy the LLMEngine object. + * + */ ~LLMEngine() override; + /** + * @brief Add new task handler to this engine. + * + * @param inputs input mappings that specifies inputs to new task handler + * @param task_handler task handler object + */ virtual void add_task_handler(user_input_mappings_t inputs, std::shared_ptr task_handler); + /** + * @brief Execute nodes in this engine and pass outputs to its task handlers. Must pass this a control message with + * a 'llm_engine' task` containing 'task_type' and 'task_dict' properties required for execution of task(s). + * + * @param input_message input control message + * @return Task>> + */ virtual Task>> run(std::shared_ptr input_message); private: diff --git a/morpheus/_lib/include/morpheus/llm/llm_node.hpp b/morpheus/_lib/include/morpheus/llm/llm_node.hpp index 05f20fefe8..70c102591b 100644 --- a/morpheus/_lib/include/morpheus/llm/llm_node.hpp +++ b/morpheus/_lib/include/morpheus/llm/llm_node.hpp @@ -30,23 +30,68 @@ namespace morpheus::llm { +/** + * @brief This class is used to implement functionality required in the processing of an LLM + * service request such as a prompt generator or LLM service client. Nodes are added to an LLMEngine + * which manages their execution including mapping of each node's input/output to parent and sibling + * node. + */ class MORPHEUS_EXPORT LLMNode : public LLMNodeBase { public: + /** + * @brief Construct a new LLMNode object. + * + */ LLMNode(); + + /** + * @brief Destroy the LLMNode object. + * + */ ~LLMNode() override; + /** + * @brief Add child node to this node and validate user input mappings. + * + * @param name child node name + * @param inputs child node input mappings + * @param node child node object + * @param is_output true if output node + * @return std::shared_ptr + */ virtual std::shared_ptr add_node(std::string name, user_input_mappings_t inputs, std::shared_ptr node, bool is_output = false); + /** + * @brief Get the input names for this node. + * + * @return std::vector + */ std::vector get_input_names() const override; + /** + * @brief Get the names of output child nodes. + * + * @return const std::vector& + */ const std::vector& get_output_node_names() const; + /** + * @brief Get number of child nodes. + * + * @return size_t + */ size_t node_count() const; + /** + * @brief Execute all child nodes and save output from output node(s) to context. + * + * @param context context for node's execution + * @return Task> + */ Task> execute(std::shared_ptr context) override; private: diff --git a/morpheus/_lib/include/morpheus/llm/llm_node_base.hpp b/morpheus/_lib/include/morpheus/llm/llm_node_base.hpp index 4c1cdaa45c..6ea3c0735b 100644 --- a/morpheus/_lib/include/morpheus/llm/llm_node_base.hpp +++ b/morpheus/_lib/include/morpheus/llm/llm_node_base.hpp @@ -27,12 +27,32 @@ namespace morpheus::llm { +/** + * @brief Base class for LLMNode. + * + */ class MORPHEUS_EXPORT LLMNodeBase { public: + /** + * @brief Destroy the LLMNodeBase object. + * + */ virtual ~LLMNodeBase() = default; - virtual std::vector get_input_names() const = 0; + /** + * @brief Virtual method for implementing how task handler gets its input names. + * + * @return std::vector + */ + virtual std::vector get_input_names() const = 0; + + /** + * @brief Virtual method for implementing the execution of a node. + * + * @param context context for node's execution + * @return Task> + */ virtual Task> execute(std::shared_ptr context) = 0; }; diff --git a/morpheus/_lib/include/morpheus/llm/llm_node_runner.hpp b/morpheus/_lib/include/morpheus/llm/llm_node_runner.hpp index 9445a488e0..8d7a70b5af 100644 --- a/morpheus/_lib/include/morpheus/llm/llm_node_runner.hpp +++ b/morpheus/_lib/include/morpheus/llm/llm_node_runner.hpp @@ -29,21 +29,62 @@ namespace morpheus::llm { +/** + * @brief This class wraps LLMNode and is responsible for node's execution. It also manages mapping of node's + * inputs to parent of sibling nodes. + */ class MORPHEUS_EXPORT LLMNodeRunner { public: + /** + * @brief Construct a new LLMNodeRunner object + * + * @param name + * @param inputs + * @param node + */ LLMNodeRunner(std::string name, input_mappings_t inputs, std::shared_ptr node); + /** + * @brief Destroy the LLMNodeRunner object + * + */ ~LLMNodeRunner(); + /** + * @brief Execute node and save outputs to context. + * + * @param context context for node's execution + * @return Task> + */ virtual Task> execute(std::shared_ptr context); + /** + * @brief Get name of node runner typically same as node name. + * + * @return const std::string& + */ const std::string& name() const; + /** + * @brief Get input mappings for this node. + * + * @return const input_mappings_t& + */ const input_mappings_t& inputs() const; + /** + * @brief Get input names from node's siblings. + * + * @return const std::vector& + */ const std::vector& sibling_input_names() const; + /** + * @brief Get input names from node's parent. + * + * @return const std::vector& + */ const std::vector& parent_input_names() const; private: diff --git a/morpheus/_lib/include/morpheus/llm/llm_task.hpp b/morpheus/_lib/include/morpheus/llm/llm_task.hpp index 72971802c5..e22af5434d 100644 --- a/morpheus/_lib/include/morpheus/llm/llm_task.hpp +++ b/morpheus/_lib/include/morpheus/llm/llm_task.hpp @@ -26,21 +26,66 @@ namespace morpheus::llm { +/** + * @brief Holds information about LLM task. Extracted by LLMEngine from input control message + * and saved to context for use by task handler(s). + * + */ struct MORPHEUS_EXPORT LLMTask { + /** + * @brief Construct a new LLMTask object. + * + */ LLMTask(); + + /** + * @brief Construct a new LLMTask object. + * + * @param task_type + * @param task_dict + */ LLMTask(std::string task_type, nlohmann::json task_dict); + /** + * @brief Destroy the LLMTask object + * + */ ~LLMTask(); + /** + * @brief task type + * + */ std::string task_type; + /** + * @brief Get size of 'task_dict'. + * + * @return size_t + */ size_t size() const; + /** + * @brief Get value in 'task_dict` corresponding to given key. + * + * @param key key of value to get from 'task_dict' + * @return const nlohmann::json& + */ const nlohmann::json& get(const std::string& key) const; + /** + * @brief Set or update item in 'task_dict'. + * + * @param key key of value in 'task_dict' to set + * @param value new value + */ void set(const std::string& key, nlohmann::json&& value); + /** + * @brief dictionary of task-related items used by task handler(s) + * + */ nlohmann::json task_dict; }; diff --git a/morpheus/_lib/include/morpheus/llm/llm_task_handler.hpp b/morpheus/_lib/include/morpheus/llm/llm_task_handler.hpp index d522b49597..04efea8510 100644 --- a/morpheus/_lib/include/morpheus/llm/llm_task_handler.hpp +++ b/morpheus/_lib/include/morpheus/llm/llm_task_handler.hpp @@ -28,6 +28,10 @@ namespace morpheus::llm { +/** + * @brief Base class for implementing for implementing task handlers used to process + * node outputs in LLMEngine. + */ class MORPHEUS_EXPORT LLMTaskHandler { public: @@ -35,7 +39,20 @@ class MORPHEUS_EXPORT LLMTaskHandler virtual ~LLMTaskHandler() = default; - virtual std::vector get_input_names() const = 0; + /** + * @brief Virtual method for implementing how task handler gets its input names. + * + * @return std::vector + */ + virtual std::vector get_input_names() const = 0; + + /** + * @brief Virtual method for implementing execution of task. Called after execution of LLM engine nodes and outputs + * saved to given context. + * + * @param context context holding outputs after execution of engine nodes + * @return Task + */ virtual Task try_handle(std::shared_ptr context) = 0; }; diff --git a/morpheus/_lib/include/morpheus/llm/llm_task_handler_runner.hpp b/morpheus/_lib/include/morpheus/llm/llm_task_handler_runner.hpp index a9203b10b8..cd0e45601e 100644 --- a/morpheus/_lib/include/morpheus/llm/llm_task_handler_runner.hpp +++ b/morpheus/_lib/include/morpheus/llm/llm_task_handler_runner.hpp @@ -27,15 +27,41 @@ namespace morpheus::llm { +/** + * @brief This class wraps LLMTaskHandler and maintains how its inputs map to node outputs in the LLMEngine. + * + */ class MORPHEUS_EXPORT LLMTaskHandlerRunner { public: + /** + * @brief Construct a new LLMTaskHandlerRunner object. + * + * @param inputs input mappings + * @param handler task handler object + */ LLMTaskHandlerRunner(input_mappings_t inputs, std::shared_ptr handler); + /** + * @brief Destroy the LLMTaskHandlerRunner object. + * + */ ~LLMTaskHandlerRunner(); + /** + * @brief Virtual method for implementing task. Called after execution of LLM engine nodes and outputs + * saved to given context. + * + * @param context context holding outputs after execution of engine nodes + * @return Task + */ virtual Task try_handle(std::shared_ptr context); + /** + * @brief Get input names for task handler. + * + * @return std::vector + */ const input_mappings_t& input_names() const { return m_inputs; diff --git a/morpheus/_lib/include/morpheus/llm/utils.hpp b/morpheus/_lib/include/morpheus/llm/utils.hpp index ad7a4f9a3c..2dda8deb0f 100644 --- a/morpheus/_lib/include/morpheus/llm/utils.hpp +++ b/morpheus/_lib/include/morpheus/llm/utils.hpp @@ -35,6 +35,14 @@ namespace morpheus::llm { */ bool MORPHEUS_EXPORT is_valid_node_name(std::string_view name); +/** + * @brief Resolves user-specified input mappings to final mappings. Handles replacement of placeholders in inputs with + * with actual internal input names provided in input_names. + * + * @param user_inputs user input mappings + * @param input_names internal input names for context + * @return input_mappings_t + */ input_mappings_t MORPHEUS_EXPORT process_input_names(user_input_mappings_t user_inputs, const std::vector& input_names);