# Debugging in jupyter notebook

messages = MessageList()

messages.add_message(
    role="system",
    content="""<configuration>
    project name: Golpex
    version: 1.3.0
    author: Golto
    description: Group of autonomous agents connected to the user via a chatbot interface.
</configuration>
<memory>
    None for now.
</memory>
<instruction>
You are Tinia, a conversational agent designed to answer the user and communicate the user's requests to other agents specialized in various fields in order to solve the user's problem together.
Before giving your answer, you can optionally use a <reasoning> tag to think about what you want to say. And to give your answer you will use <assistant_output>.
To call agents, use the <calling> tag inside <assistant_output> and in this tag, use the <agent name="..."> tag specifying the name of each agent. Note: You can call multiple agents at once.
</instruction>
<tools>
    None
</tools>
<agents>
- Tinia : (you) | Conversational agent that bridges the gap between the user and the rest of the agents. She manages communication between each entity.
- Pixela : She can creates, edits and manages images. If you have an image related problem, call her.
- Ixabel: She manages files and repositories. If you need to create, edit, delete a file or supervize a file tree, she can do it for you.
- Sapphira: Need an information? Ask her as she has access to wide variety of databases and knowledge.
</agents>
"""
)

messages.add_message(
    role="user",
    content="""<memory>
    None for now.
</memory>
<information>
    The user is trying to build an AI-based chatbot interface to connect autonomous agents for problem-solving.
</information>
<user_input>
Can you suggest how to structure communication between agents efficiently?
</user_input>
"""
)

messages.add_message(
    role="assistant",
    content="""<reasoning>
In order to efficiently structure communication between multiple autonomous agents, the system can adopt a message-passing architecture. This ensures each agent operates independently and communicates via a centralized hub or a peer-to-peer network.

Key elements to consider:
1. **Message Format**: Each agent should communicate in a standardized message format, such as JSON or XML.
2. **Routing**: A central message handler (or router) will be necessary to direct queries to the appropriate agent. This could be rule-based or rely on a directory of agent capabilities.
3. **Concurrency**: Agents should operate asynchronously to avoid bottlenecks, making use of an event-driven or message queue system.
4. **Error Handling**: Introduce feedback loops to handle failures in communication, such as timeouts or retries.
5. **Agent Identification**: Each agent should have a unique identifier to track interactions.
</reasoning>
<assistant_output>
To implement the communication structure, you can start by creating a central hub (or router) to manage messages and route them between agents. You may use technologies like RabbitMQ or Redis for message brokering.

Next, define a message schema (JSON/XML) with fields for:
- **sender_id**: Unique identifier for the agent sending the message.
- **receiver_id**: Target agent's identifier.
- **content**: The actual data or request being communicated.
- **timestamp**: Time of message creation.
- **status**: Track if the message was delivered successfully or if it needs retries.

This will help agents work asynchronously while ensuring robust communication.
</assistant_output>
"""
)

messages.add_message(
    role="user",
    content="""<memory>
    The user is trying to build an AI-based chatbot interface to connect autonomous agents for problem-solving.
</memory>
<information>
    <environment_variables>
        empty
    </environment_variables>
</information>
<user_input>
Can you create an image of a blue-ish tree in a cartoon world?
</user_input>
"""
)

## ------------------------------



messages.add_message(
    role="assistant",
    content="""<reasoning>
The user wants an image of a blue tree in a cartoon style. I'll call Pixela, our image specialist agent, to handle this task.
</reasoning>
<assistant_output>
<calling>
    <agent name="Pixela">
        <message>
            {
                "request": "Create an image of a blue-ish tree in a cartoon world.",
                "format": "PNG"
            }
        </message>
    </agent>
</calling>
Of course, I can help with that. We'll create a blue-ish cartoon tree for you. Please hold on a moment while I connect you with our image specialist agent, Pixela.
</assistant_output>
"""
)

messages.continue_last_message("""
<call_results>
    <agent name="Pixela">
        Hi Tinia, I create the image you asked me. You can find "blue_tree_cartoon.png" on the environment variables.
    </agent>
</call_results>

<assistant_output>""")


# ./agent.py

from root.inferences.client import Client
from root.inferences.default import Default

from root.datatypes.messages import MessageList

"""
System:
    - configuration
    - memory
    - instruction
    - tools
    - agents

User:
    - memory
    - information
    - user_input

Assistant:
    - reasoning (optional)
    - assistant_output
        - calling
            - tool
            - agent

    - call_results (optional, if `calling`) -> GOTO assistant_output
        - tool
        - agent
"""


class Agent:

    CONFIGURATION = {
        "project_name": "Golpex",
        "version": "prototype 3.1.0",
        "author": "Golto",
        "description": "Group of autonomous agents connected to the user via a chatbot interface."
    }
    
    def __init__(self, name: str, job: str) -> None:
        self.name = name
        self.job = job
        self.agent_calls = {}
        self.tools = {}
        self.client = Client(model_map=Default().model_map)

        self.messages = MessageList()
        self._init_system()
        

    def _init_system(self):
        content = ""
        content += self._init_configuration()
        content += self._init_memory()
        content += self._init_instructions()
        content += self._init_tools()
        content += self._init_agents()
        self.messages.add_message(role="system", content=content)
    
    def _init_configuration(self) -> str:
        return ""
    
    def _init_memory(self) -> str:
        return ""
    
    def _init_instructions(self) -> str:
        return ""
    
    def _init_tools(self) -> str:
        return ""
    
    def _init_agents(self) -> str:
        return ""

# On a besoin d'aide pour gérer des des tags XML, il nous faudrait un module qui puisse simplifier la gestion des prompts avec xml, de sorte qu'on puisse créer les messages facilement.