Skip to content

∞ General Executor

Documentation

  • Class name: LLMAgentExecutor
  • Category: SALT/Language Toolkit/Agents/Tools
  • Output node: False

The LLMAgentExecutor node is designed to orchestrate the execution of language model agents within a given environment, leveraging a combination of user queries, document contexts, and model configurations to generate responses or actions. It integrates various components such as file creation, user simulation, and context management to facilitate complex interactions and generate outputs based on the specified parameters.

Input types

Required

  • llm_model
    • Specifies the language model to be used for execution, including model details and API keys, enabling the node to configure and utilize the model appropriately.
    • Comfy dtype: LLM_MODEL
    • Python dtype: Dict[str, Any]
  • query
    • The user's input or question that initiates the execution process, serving as the starting point for the interaction with the agent.
    • Comfy dtype: STRING
    • Python dtype: str

Optional

  • documents_or_string
    • Optional context provided as either a list of documents or a single string, which is used to enrich the agent's understanding and response generation.
    • Comfy dtype: *
    • Python dtype: Union[List[Document], str, None]
  • summary_method
    • Defines the method used to summarize the interaction or content, influencing how the agent processes and presents information.
    • Comfy dtype: COMBO[STRING]
    • Python dtype: List[str]
  • max_turns
    • Limits the number of interaction turns between the user and the agent, controlling the depth of the conversation.
    • Comfy dtype: INT
    • Python dtype: int
  • clear_history
    • Determines whether to reset the agent's memory before starting the execution, affecting the continuity of context.
    • Comfy dtype: BOOLEAN
    • Python dtype: bool

Output types

  • file_path
    • Comfy dtype: STRING
    • The path to the generated file as a result of the execution process.
    • Python dtype: str
  • chat_history
    • Comfy dtype: STRING
    • A record of the chat history between the user and the agent throughout the execution.
    • Python dtype: str
  • summary
    • Comfy dtype: STRING
    • A summary of the interaction or content generated by the agent, based on the specified summarization method.
    • Python dtype: str

Usage tips

  • Infra type: CPU
  • Common nodes: unknown

Source code

class LLMAgentExecutor:
    @classmethod
    def INPUT_TYPES(cls):
        return {
            "required": {
                "llm_model": ("LLM_MODEL",),
                "query": ("STRING", {
                    "multiline": True,
                    "dynamicPrompts": False,
                    "default": "Generate a file using the provided data."
                }),
            },
            "optional": {
                "documents_or_string": (WILDCARD,),
                "summary_method": ([
                    "last_msg",
                    "reflection_with_llm",
                ],),
                "max_turns": ("INT", {"default": 10}),
                "clear_history": ("BOOLEAN", {"default": True})
            }
        }

    RETURN_TYPES = ("STRING", "STRING", "STRING")
    RETURN_NAMES = ("file_path", "chat_history", "summary")

    FUNCTION = "generate"
    CATEGORY = f"{MENU_NAME}/{SUB_MENU_NAME}/Agents/Tools"

    def generate(self, llm_model, query, documents_or_string=None, summary_method="reflection_with_llm", max_turns=10, clear_history=True):
        llm_config = {"config_list": [{"model": llm_model["llm"].model, "api_key": llm_model["llm"].api_key}]} if llm_model is not None else False

        working_dir = get_full_path(0, 'outputs')
        os.makedirs(working_dir, exist_ok=True)

        file_creator = GenericCreator(name="file_creator", llm_config=llm_config, n_iters=max_turns, summary_method=summary_method, clear_history=clear_history)

        user_proxy = UserProxyAgent(
            name="User", human_input_mode="NEVER", max_consecutive_auto_reply=0, code_execution_config={"use_docker": False}
        )

        context = ""
        if documents_or_string:
            if isinstance(documents_or_string, list):
                for doc in documents_or_string:
                    if isinstance(doc, Document):
                        context += repr(doc.text) + "\n\n"
                        context += "Metadata:\n" + repr(json.dumps(doc.metadata)) + "\n\n"
                    elif isinstance(doc, str):
                        context += repr(doc) + "\n\n"
            elif isinstance(documents_or_string, str):
                context += repr(documents_or_string)

        full_message = query
        if context:
            full_message += f"\n\nData Context:\n{context}"

        proxy_result = user_proxy.initiate_chat(
            file_creator, 
            message=full_message,
            summary_method=summary_method,
            max_turns=max_turns,
            clear_history=clear_history,
        )

        chat_result = file_creator.chat_result
        if chat_result:
            summary = chat_result.summary
            chat_history = ""
            for message in chat_result.chat_history:
                chat_history += "- " + str(message["content"]) + "\n\n"
        else:
            summary = "Not available"
            chat_history = "Not available"

        result_path = file_creator.result_path
        if not result_path:
            logger.error("Failed to create the result file.")
            return None

        return (result_path, chat_history, summary)