From 678c2e852541f3ff4e766a4b35aad99ac6a1f816 Mon Sep 17 00:00:00 2001 From: gautamgambhir97 Date: Wed, 27 Nov 2024 14:58:45 +0530 Subject: [PATCH] feat: adding links and github code segments for the advanced examples --- pages/examples/advanced/async-loops.mdx | 200 ++-- pages/examples/advanced/deltaV-dialogues.mdx | 337 ++++--- .../advanced/open-dialogue-chitchat.mdx | 851 ++++++++++-------- .../advanced/predefined-dialogue-chitchat.mdx | 704 +++++++++------ 4 files changed, 1221 insertions(+), 871 deletions(-) diff --git a/pages/examples/advanced/async-loops.mdx b/pages/examples/advanced/async-loops.mdx index f171ec576..54ed596a5 100644 --- a/pages/examples/advanced/async-loops.mdx +++ b/pages/examples/advanced/async-loops.mdx @@ -1,4 +1,4 @@ -import { CodeGroup, DocsCode } from "../../../components/code"; +import { CodeGroup, DocsCode, CodeSegment, GithubCodeSegment } from "../../../components/code"; # Agent Asynchronous Loops @@ -6,6 +6,8 @@ import { CodeGroup, DocsCode } from "../../../components/code"; In this example, we demonstrate how to use agents to communicate and exchange status updates in a decentralized system. Agents will send status messages to each other and handle acknowledgments in response. This example is useful for understanding how agents can interact, process messages, and maintain state. +Please check out the example code in our [examples repo ↗️](https://github.com/fetchai/uAgent-Examples/tree/main/1-uagents/examples/advanced/async-loops) to run this locally. + ### Supporting documentation - [Creating an agent ↗️](/guides/agents/create-a-uagent) @@ -17,102 +19,124 @@ In this example, we demonstrate how to use agents to communicate and exchange st #### Script 1 - + + + + - ```py copy filename="external_loop_attach.py" - import asyncio - import contextlib - - from uagents import Agent, Bureau, Context - - loop = asyncio.get_event_loop() - - agent = Agent( - name="looper", - seed="", - ) - - bureau = Bureau( - agents=[agent], - ) - - @agent.on_event("startup") - async def startup(ctx: Context): - ctx.logger.info(">>> Looper is starting up.") - - @agent.on_event("shutdown") - async def shutdown(ctx: Context): - ctx.logger.info(">>> Looper is shutting down.") - - async def coro(): - while True: - print("Doing hard work...") - await asyncio.sleep(1) - - if __name__ == "__main__": - print("Attaching the agent or bureau to the external loop...") - loop.create_task(coro()) - - # > when attaching the agent to the external loop - loop.create_task(agent.run_async()) - - # > when attaching a bureau to the external loop - # loop.create_task(bureau.run_async()) - - with contextlib.suppress(KeyboardInterrupt): - loop.run_forever() - ``` - + ```py copy filename="external_loop_attach.py" + + import asyncio + import contextlib + + from uagents import Agent, Bureau, Context + + loop = asyncio.get_event_loop() + + agent = Agent( + name="looper", + seed="", + ) + + bureau = Bureau( + agents=[agent], + ) + + @agent.on_event("startup") + async def startup(ctx: Context): + ctx.logger.info(">>> Looper is starting up.") + + @agent.on_event("shutdown") + async def shutdown(ctx: Context): + ctx.logger.info(">>> Looper is shutting down.") + + async def coro(): + while True: + print("Doing hard work...") + await asyncio.sleep(1) + + if __name__ == "__main__": + print("Attaching the agent or bureau to the external loop...") + loop.create_task(coro()) + + # > when attaching the agent to the external loop + loop.create_task(agent.run_async()) + + # > when attaching a bureau to the external loop + # loop.create_task(bureau.run_async()) + + with contextlib.suppress(KeyboardInterrupt): + loop.run_forever() + +``` + This script demonstrates how to run an agent using an external event loop. For this example to run correctly, remember to provide a `seed` phrase to the agent. It initializes an agent and attaches it to a loop where it performs continuous background work (`coro()` function) alongside the agent's operations. You can choose to run either the agent or the entire `bureau` with the external loop. This approach provides greater flexibility when integrating the agent with other asynchronous tasks. #### Script 2 - - - ```py copy filename="external_loop_run.py" - import asyncio - - from uagents import Agent, Bureau, Context - - loop = asyncio.get_event_loop() - - agent = Agent( - name="looper", - seed="", - loop=loop, - ) - - bureau = Bureau( - agents=[agent], - loop=loop, - ) + + + + - @agent.on_event("startup") - async def startup(ctx: Context): - ctx.logger.info(">>> Looper is starting up.") - - @agent.on_event("shutdown") - async def shutdown(ctx: Context): - ctx.logger.info(">>> Looper is shutting down.") - - async def coro(): - while True: - print("Doing hard work...") - await asyncio.sleep(1) - - if __name__ == "__main__": - print("Starting the external loop from the agent or bureau...") - loop.create_task(coro()) - - # > when starting the external loop from the agent - agent.run() + + ```py copy filename="external_loop_run.py" + + import asyncio + + from uagents import Agent, Bureau, Context + + loop = asyncio.get_event_loop() + + agent = Agent( + name="looper", + seed="", + loop=loop, + ) + + bureau = Bureau( + agents=[agent], + loop=loop, + ) + + @agent.on_event("startup") + async def startup(ctx: Context): + ctx.logger.info(">>> Looper is starting up.") + + @agent.on_event("shutdown") + async def shutdown(ctx: Context): + ctx.logger.info(">>> Looper is shutting down.") + + async def coro(): + while True: + print("Doing hard work...") + await asyncio.sleep(1) + + if __name__ == "__main__": + print("Starting the external loop from the agent or bureau...") + loop.create_task(coro()) + + # > when starting the external loop from the agent + agent.run() + + # > when starting the external loop from the bureau + # bureau.run() + +``` + - # > when starting the external loop from the bureau - # bureau.run() - ``` - This script shows how to run an agent with its own **internal event loop**. For this example to run correctly, remember to provide a `seed` phrase to the agent. The agent is initialized with the `loop`, and both the agent and its background coroutine (`coro()` function) run within the same loop. This setup simplifies the integration by keeping everything within a single event `loop`, which can be advantageous for applications where you want the agent's lifecycle tightly coupled with its event handling function. diff --git a/pages/examples/advanced/deltaV-dialogues.mdx b/pages/examples/advanced/deltaV-dialogues.mdx index c2d3ed473..f18dc2953 100644 --- a/pages/examples/advanced/deltaV-dialogues.mdx +++ b/pages/examples/advanced/deltaV-dialogues.mdx @@ -1,5 +1,7 @@ import { Callout } from 'nextra/components' +import { CodeGroup, DocsCode, CodeSegment, GithubCodeSegment } from "../../../components/code"; + # DeltaV Compatible Dialogues Agent In this example we will create an agent on Agentverse which can handle multiple stocks price request in deltaV using [Dialogues ↗️](/guides/agents/advanced/dialogues). @@ -8,6 +10,8 @@ In this example we will create an agent on Agentverse which can handle multiple To test agents using **Dialogues or ChitChat** on DeltaV, users must select the **Next generation** personality type in [DeltaV ↗️](https://deltav.agentverse.ai/) when providing your query through the dedicated bar. The **Next Generation AI Engine** personality stands as a significant AI Engine personality type offering _enhanced scalability_, _reliability_, and _flexibility_. The major key features include advanced context understanding, improved function recommendations, and the ability to handle diverse dialogue formats. +Please check out the example code in our [examples repo ↗️](https://github.com/fetchai/uAgent-Examples/blob/main/1-uagents/examples/advanced/deltaV-dialogues/deltav-dialogues.py) to run this locally. + ## Guide - [How to use Dialogues ↗️](/guides/agents/dialogues) @@ -23,150 +27,239 @@ In this example we will create an agent on Agentverse which can handle multiple Open [Agentverse ↗️](https://agentverse.ai/), create a new agent and include the below script. We need to import predefined AI engine dialogue and Dialogue Messages: - ```python - # Import required libraries - import json - from ai_engine.chitchat import ChitChatDialogue - from ai_engine.messages import DialogueMessage - from uagents import Agent, Context, Model - ``` + + + + -## Step 2: Define dialogues message + + ```py copy filename="deltav-dialogues.py" -Each dialogue transition needs a separate message: + # Import required libraries + import json + from ai_engine.chitchat import ChitChatDialogue + from ai_engine.messages import DialogueMessage + from uagents import Agent, Context, Model + - ```python - class InitiateChitChatDialogue(Model): - """I initiate ChitChat dialogue request""" - pass +``` + - class AcceptChitChatDialogue(Model): - """I accept ChitChat dialogue request""" - pass + - class ChitChatDialogueMessage(DialogueMessage): - """ChitChat dialogue message""" - pass +## Step 2: Define dialogues message - class ConcludeChitChatDialogue(Model): - """I conclude ChitChat dialogue request""" - pass +Each dialogue transition needs a separate message: - class RejectChitChatDialogue(Model): - """I reject ChitChat dialogue request""" - pass - ``` + + + + + + + ```py copy filename="deltav-dialogues.py" + + + class InitiateChitChatDialogue(Model): + """I initiate ChitChat dialogue request""" + pass + + class AcceptChitChatDialogue(Model): + """I accept ChitChat dialogue request""" + pass + + class ChitChatDialogueMessage(DialogueMessage): + """ChitChat dialogue message""" + pass + + class ConcludeChitChatDialogue(Model): + """I conclude ChitChat dialogue request""" + pass + + class RejectChitChatDialogue(Model): + """I reject ChitChat dialogue request""" + pass + + +``` + + + ## Step 3: Define functions to get symbol and stock price Setup the functions making API calls to get ticker symbol and stock price: - ```python - async def get_symbol(company_name): - url = f"https://www.alphavantage.co/query?function=SYMBOL_SEARCH&keywords={company_name}&apikey={API_KEY}" + + + + + + + ```py copy filename="deltav-dialogues.py" + + + async def get_symbol(company_name): + url = f"https://www.alphavantage.co/query?function=SYMBOL_SEARCH&keywords={company_name}&apikey={API_KEY}" + + response = requests.get(url) + data = response.json() + + if 'bestMatches' in data and data['bestMatches']: + first_match = data['bestMatches'][0] + symbol = first_match['1. symbol'] + return symbol + else: + return f"No symbol found for {company_name}." + + async def get_stock_price(symbol): + url = f"https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol={symbol}&interval=1min&apikey={API_KEY}" + + response = requests.get(url) + data = response.json() + print(data) + + if 'Time Series (1min)' in data: + latest_time = sorted(data['Time Series (1min)'].keys())[0] + latest_data = data['Time Series (1min)'][latest_time] + current_price = latest_data['1. open'] + return current_price + else: + return "Error: Unable to fetch stock price." + + +``` + + + - response = requests.get(url) - data = response.json() +## Step 4: instantiate the dialogues - if 'bestMatches' in data and data['bestMatches']: - first_match = data['bestMatches'][0] - symbol = first_match['1. symbol'] - return symbol - else: - return f"No symbol found for {company_name}." + + + + - async def get_stock_price(symbol): - url = f"https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol={symbol}&interval=1min&apikey={API_KEY}" + + ```py copy filename="deltav-dialogues.py" - response = requests.get(url) - data = response.json() - print(data) + + chitchat_dialogue = ChitChatDialogue( + version="", #example 0.11.1 + storage=agent.storage, + ) + - if 'Time Series (1min)' in data: - latest_time = sorted(data['Time Series (1min)'].keys())[0] - latest_data = data['Time Series (1min)'][latest_time] - current_price = latest_data['1. open'] - return current_price - else: - return "Error: Unable to fetch stock price." - ``` +``` + -## Step 4: instantiate the dialogues + - ```python - chitchat_dialogue = ChitChatDialogue( - version="", #example 0.11.1 - storage=agent.storage, - ) - ``` ## Step 5: Define different event handlers for the dialogues - ```python - @chitchat_dialogue.on_initiate_session(InitiateChitChatDialogue) - async def start_chitchat( - ctx: Context, - sender: str, - msg: InitiateChitChatDialogue, - ): - ctx.logger.info(f"Received init message from {sender} Session: {ctx.session}") - # do something when the dialogue is initiated - await ctx.send(sender, AcceptChitChatDialogue()) - - @chitchat_dialogue.on_start_dialogue(AcceptChitChatDialogue) - async def accepted_chitchat( - ctx: Context, - sender: str, - _msg: AcceptChitChatDialogue, - ): - ctx.logger.info( - f"session with {sender} was accepted. This shouldn't be called as this agent is not the initiator." - ) - - @chitchat_dialogue.on_reject_session(RejectChitChatDialogue) - async def reject_chitchat( - ctx: Context, - sender: str, - _msg: RejectChitChatDialogue, - ): - # do something when the dialogue is rejected and nothing has been sent yet - ctx.logger.info(f"Received conclude message from: {sender}") - - @chitchat_dialogue.on_continue_dialogue(ChitChatDialogueMessage) - async def continue_chitchat( - ctx: Context, - sender: str, - msg: ChitChatDialogueMessage, - ): - # do something when the dialogue continues - ctx.logger.info(f"Received message: {msg.user_message} from: {sender}") - symbol = await get_symbol(msg.user_message) - stock_price = await get_stock_price(symbol) - final_string = f'The price for your {msg.user_message} is $ {stock_price}' - try: - await ctx.send( - sender, - ChitChatDialogueMessage( - type="agent_message", - agent_message=final_string - ), - ) - except EOFError: - await ctx.send(sender, ConcludeChitChatDialogue()) - - @chitchat_dialogue.on_end_session(ConcludeChitChatDialogue) - async def conclude_chitchat( - ctx: Context, - sender: str, - _msg: ConcludeChitChatDialogue, - ): - # do something when the dialogue is concluded after messages have been exchanged - ctx.logger.info(f"Received conclude message from: {sender}; accessing history:") - ctx.logger.info(chitchat_dialogue.get_conversation(ctx.session)) - - agent.include(chitchat_dialogue, publish_manifest=True) - - ``` + + + + + + + ```py copy filename="deltav-dialogues.py" + + + @chitchat_dialogue.on_initiate_session(InitiateChitChatDialogue) + async def start_chitchat( + ctx: Context, + sender: str, + msg: InitiateChitChatDialogue, + ): + ctx.logger.info(f"Received init message from {sender} Session: {ctx.session}") + # do something when the dialogue is initiated + await ctx.send(sender, AcceptChitChatDialogue()) + + @chitchat_dialogue.on_start_dialogue(AcceptChitChatDialogue) + async def accepted_chitchat( + ctx: Context, + sender: str, + _msg: AcceptChitChatDialogue, + ): + ctx.logger.info( + f"session with {sender} was accepted. This shouldn't be called as this agent is not the initiator." + ) + + @chitchat_dialogue.on_reject_session(RejectChitChatDialogue) + async def reject_chitchat( + ctx: Context, + sender: str, + _msg: RejectChitChatDialogue, + ): + # do something when the dialogue is rejected and nothing has been sent yet + ctx.logger.info(f"Received conclude message from: {sender}") + + @chitchat_dialogue.on_continue_dialogue(ChitChatDialogueMessage) + async def continue_chitchat( + ctx: Context, + sender: str, + msg: ChitChatDialogueMessage, + ): + # do something when the dialogue continues + ctx.logger.info(f"Received message: {msg.user_message} from: {sender}") + symbol = await get_symbol(msg.user_message) + stock_price = await get_stock_price(symbol) + final_string = f'The price for your {msg.user_message} is $ {stock_price}' + try: + await ctx.send( + sender, + ChitChatDialogueMessage( + type="agent_message", + agent_message=final_string + ), + ) + except EOFError: + await ctx.send(sender, ConcludeChitChatDialogue()) + + @chitchat_dialogue.on_end_session(ConcludeChitChatDialogue) + async def conclude_chitchat( + ctx: Context, + sender: str, + _msg: ConcludeChitChatDialogue, + ): + # do something when the dialogue is concluded after messages have been exchanged + ctx.logger.info(f"Received conclude message from: {sender}; accessing history:") + ctx.logger.info(chitchat_dialogue.get_conversation(ctx.session)) + + agent.include(chitchat_dialogue, publish_manifest=True) + + +``` + + + ## Step 6: Save the API key and Run the script in agentverse diff --git a/pages/examples/advanced/open-dialogue-chitchat.mdx b/pages/examples/advanced/open-dialogue-chitchat.mdx index 50f623db3..c9bb2bb7e 100644 --- a/pages/examples/advanced/open-dialogue-chitchat.mdx +++ b/pages/examples/advanced/open-dialogue-chitchat.mdx @@ -1,5 +1,5 @@ import { Callout } from 'nextra/components' -import { CodeGroup, DocsCode } from "../../../components/code"; +import { CodeGroup, DocsCode, CodeSegment, GithubCodeSegment } from "../../../components/code"; # Open Dialogue Chit-Chat @@ -7,6 +7,8 @@ import { CodeGroup, DocsCode } from "../../../components/code"; This example demonstrates how to set up and execute a simple agent-based dialogue using the ChitChat Dialogue system. Agent 2 will initiate a conversation with Agent 1, which will respond and continue the interaction. This interaction showcases basic dialogue initiation, message exchange, and dialogue conclusion. Each step and state transition within the ChitChat Dialogue is visible and interactive +Please check out the example code in our [examples repo ↗️](https://github.com/fetchai/uAgent-Examples/tree/main/1-uagents/examples/advanced/open-dialogue-chitchat) to run this locally. + ### Guide - [How to use Dialogues ↗️](/guides/agents/dialogues) @@ -47,156 +49,223 @@ This script sets up the `ChitChatDialogue` class, This system includes nodes rep - Import required libraries. - ```python - # Import required libraries + + + + + + + ```py copy filename="chitchat.py" + + # Import required libraries + + from typing import Type + from uagents import Model + from uagents.experimental.dialogues import Dialogue, Edge, Node + + +``` + - from typing import Type - from uagents import Model - from uagents.experimental.dialogues import Dialogue, Edge, Node - ``` + - Define `nodes` (state) of dialogues like default, initiate, chitchat and conclude state. - ```python - # Define node of dialogue - default_state = Node( - name="Default State", - description=( - "This is the default state of the dialogue. Every session starts in " - "this state and is automatically updated once the dialogue starts." - ) - ) - init_state = Node( - name="Initiated", - description=( - "This is the initial state of the dialogue that is only available at " - "the receiving agent." - ), - ) - chatting_state = Node( - name="Chit Chatting", - description="This is the state in which messages are exchanged.", - ) - end_state = Node( - name="Concluded", - description="This is the state after the dialogue has been concluded.", - ) - ``` + + + + + + + ```py copy filename="chitchat.py" + + # Define node of dialogue + default_state = Node( + name="Default State", + description=( + "This is the default state of the dialogue. Every session starts in " + "this state and is automatically updated once the dialogue starts." + ) + ) + init_state = Node( + name="Initiated", + description=( + "This is the initial state of the dialogue that is only available at " + "the receiving agent." + ), + ) + chatting_state = Node( + name="Chit Chatting", + description="This is the state in which messages are exchanged.", + ) + end_state = Node( + name="Concluded", + description="This is the state after the dialogue has been concluded.", + ) + + +``` + + + - Define `edges` (transition) of dialogues like initiate session, reject session, start dialogue, continue dialogue and end session. - ```python - # Edge definition for the dialogue transitions - init_session = Edge( - name="initiate_session", - description="Every dialogue starts with this transition.", - parent=None, - child=init_state, - ) - reject_session = Edge( - name="reject_session", - description=("This is the transition for when the dialogue is rejected"), - parent=init_state, - child=end_state, - ) - start_dialogue = Edge( - name="start_dialogue", - description="This is the transition from initiated to chit chatting.", - parent=init_state, - child=chatting_state, - ) - cont_dialogue = Edge( - name="continue_dialogue", - description=( - "This is the transition from one dialogue message to the next, " - "i.e. for when the dialogue continues." - ), - parent=chatting_state, - child=chatting_state, - ) - end_session = Edge( - name="end_session", - description="This is the transition for when the session is ended.", - parent=chatting_state, - child=end_state, - ) - ``` + + + + + + + ```py copy filename="chitchat.py" + + # Edge definition for the dialogue transitions + init_session = Edge( + name="initiate_session", + description="Every dialogue starts with this transition.", + parent=None, + child=init_state, + ) + reject_session = Edge( + name="reject_session", + description=("This is the transition for when the dialogue is rejected"), + parent=init_state, + child=end_state, + ) + start_dialogue = Edge( + name="start_dialogue", + description="This is the transition from initiated to chit chatting.", + parent=init_state, + child=chatting_state, + ) + cont_dialogue = Edge( + name="continue_dialogue", + description=( + "This is the transition from one dialogue message to the next, " + "i.e. for when the dialogue continues." + ), + parent=chatting_state, + child=chatting_state, + ) + end_session = Edge( + name="end_session", + description="This is the transition for when the session is ended.", + parent=chatting_state, + child=end_state, + ) + + +``` + + + - Define `ChitChatDialogue` class and include nodes and edges into it. These acts as rule for chit chat dialogues. - ```python - class ChitChatDialogue(Dialogue): - """ - This is the specific definition of the rules for the chit-chat dialogue - The rules will be predefined and the actual messages will be passed into it - """ - - def __init__( - self, - version: str | None = None, - agent_address: str | None = None, - ) -> None: - super().__init__( - name="ChitChatDialogue", - version=version, - agent_address=agent_address, - nodes=[ - default_state, - init_state, - chatting_state, - end_state, - ], - edges=[ - init_session, - reject_session, - start_dialogue, - cont_dialogue, - end_session, - ], - ) - - def on_initiate_session(self, model: Type[Model]): - """ - This handler is triggered when the initial message of the - dialogue is received. From here you can either accept or reject. - Logic that is needed to complete any kind of handshake or considers - global agent state should go here. - """ - return super()._on_state_transition(init_session.name, model) - - def on_reject_session(self, model: Type[Model]): - """ - This handler is triggered when a reject message is returned on - the initial message. - Implement this if you need to clean up session data. - """ - return super()._on_state_transition(reject_session.name, model) - - def on_start_dialogue(self, model: Type[Model]): - """ - This handler is triggered when an accept message is returned on - the initial message. - Include logic to complete any handshake on the sender side and - prepare the actual message exchange. - """ - return super()._on_state_transition(start_dialogue.name, model) - - def on_continue_dialogue(self, model: Type[Model]): - """ - This handler is triggered for every incoming "chitchat" message - once the session has been accepted. - Any additional stateful information within a dialogue needs to be - persisted explicitly to access it at a later point in the dialogue. - """ - return super()._on_state_transition(cont_dialogue.name, model) - - def on_end_session(self, model: Type[Model]): - """ - This handler is triggered once the other party has ended the dialogue. - Any final conclusion or cleanup goes here. - """ - return super()._on_state_transition(end_session.name, model) - ``` + + + + + + + ```py copy filename="chitchat.py" + + + class ChitChatDialogue(Dialogue): + """ + This is the specific definition of the rules for the chit-chat dialogue + The rules will be predefined and the actual messages will be passed into it + """ + + def __init__( + self, + version: str | None = None, + agent_address: str | None = None, + ) -> None: + super().__init__( + name="ChitChatDialogue", + version=version, + nodes=[ + default_state, + init_state, + chatting_state, + end_state, + ], + edges=[ + init_session, + reject_session, + start_dialogue, + cont_dialogue, + end_session, + ], + ) + + def on_initiate_session(self, model: Type[Model]): + """ + This handler is triggered when the initial message of the + dialogue is received. From here you can either accept or reject. + Logic that is needed to complete any kind of handshake or considers + global agent state should go here. + """ + return super()._on_state_transition(init_session.name, model) + + def on_reject_session(self, model: Type[Model]): + """ + This handler is triggered when a reject message is returned on + the initial message. + Implement this if you need to clean up session data. + """ + return super()._on_state_transition(reject_session.name, model) + + def on_start_dialogue(self, model: Type[Model]): + """ + This handler is triggered when an accept message is returned on + the initial message. + Include logic to complete any handshake on the sender side and + prepare the actual message exchange. + """ + return super()._on_state_transition(start_dialogue.name, model) + + def on_continue_dialogue(self, model: Type[Model]): + """ + This handler is triggered for every incoming "chitchat" message + once the session has been accepted. + Any additional stateful information within a dialogue needs to be + persisted explicitly to access it at a later point in the dialogue. + """ + return super()._on_state_transition(cont_dialogue.name, model) + + def on_end_session(self, model: Type[Model]): + """ + This handler is triggered once the other party has ended the dialogue. + Any final conclusion or cleanup goes here. + """ + return super()._on_state_transition(end_session.name, model) + +``` + + + The contents of this script are to be shared between the agents that want to use this dialogue. This defines the structure of the specific dialogue and the messages that are expected to be exchanged. @@ -227,124 +296,135 @@ The contents of this script are to be shared between the agents that want to use - - - - ```python copy filename="agent1.py" - # Import required libraries - import json - - from uagents import Agent, Context, Model - from uagents.setup import fund_agent_if_low - from dialogues.chitchat import ChitChatDialogue - - CHAT_AGENT_ADDRESS = "" - - agent = Agent( - name="chit_agent", - seed="", - port=8001, - endpoint="http://127.0.0.1:8001/submit", - ) - - fund_agent_if_low(agent.wallet.address()) - - # Define dialogue messages; each transition needs a separate message - class InitiateChitChatDialogue(Model): - pass - - class AcceptChitChatDialogue(Model): - pass - - class ChitChatDialogueMessage(Model): - text: str - - class ConcludeChitChatDialogue(Model): - pass - - class RejectChitChatDialogue(Model): - pass - - # Instantiate the dialogues - chitchat_dialogue = ChitChatDialogue( - version="0.1", - agent_address=agent.address, - ) - - # Get an overview of the dialogue structure - print("Dialogue overview:") - print(json.dumps(chitchat_dialogue.get_overview(), indent=4)) - print("---") - - @chitchat_dialogue.on_initiate_session(InitiateChitChatDialogue) - async def start_chitchat( - ctx: Context, - sender: str, - _msg: InitiateChitChatDialogue, - ): - ctx.logger.info(f"Received init message from {sender}") - # Do something when the dialogue is initiated - await ctx.send(sender, AcceptChitChatDialogue()) - - @chitchat_dialogue.on_start_dialogue(AcceptChitChatDialogue) - async def accept_chitchat( - ctx: Context, - sender: str, - _msg: AcceptChitChatDialogue, - ): - ctx.logger.info( - f"session with {sender} was accepted. I'll say 'Hello!' to start the ChitChat" - ) - # Do something after the dialogue is started; e.g. send a message - await ctx.send(sender, ChitChatDialogueMessage(text="Hello!")) - - @chitchat_dialogue.on_reject_session(RejectChitChatDialogue) - async def reject_chitchat( - ctx: Context, - sender: str, - _msg: RejectChitChatDialogue, - ): - # Do something when the dialogue is rejected and nothing has been sent yet - ctx.logger.info(f"Received reject message from: {sender}") - - @chitchat_dialogue.on_continue_dialogue(ChitChatDialogueMessage) - async def continue_chitchat( - ctx: Context, - sender: str, - msg: ChitChatDialogueMessage, - ): - # Do something when the dialogue continues - ctx.logger.info(f"Received message: {msg.text}") - try: - my_msg = input("Please enter your message:\n> ") - if my_msg != "exit": - await ctx.send(sender, ChitChatDialogueMessage(text=my_msg)) - else: - await ctx.send(sender, ConcludeChitChatDialogue()) - ctx.logger.info( - f"Received conclude message from: {sender}; accessing history:" - ) - ctx.logger.info(chitchat_dialogue.get_conversation(ctx.session)) - except EOFError: - await ctx.send(sender, ConcludeChitChatDialogue()) - - @chitchat_dialogue.on_end_session(ConcludeChitChatDialogue) - async def conclude_chitchat( - ctx: Context, - sender: str, - _msg: ConcludeChitChatDialogue, - ): - # Do something when the dialogue is concluded after messages have been exchanged - ctx.logger.info(f"Received conclude message from: {sender}; accessing history:") - ctx.logger.info(chitchat_dialogue.get_conversation(ctx.session)) - - agent.include(chitchat_dialogue) - - if __name__ == "__main__": - print(f"Agent address: {agent.address}") - agent.run() - ``` - + + + + + + + ```py copy filename="agent1.py" + + # Import required libraries + import json + + from uagents import Agent, Context, Model + from uagents.setup import fund_agent_if_low + from dialogues.chitchat import ChitChatDialogue + + CHAT_AGENT_ADDRESS = "" + + agent = Agent( + name="chit_agent", + seed="", + port=8001, + endpoint="http://127.0.0.1:8001/submit", + ) + + fund_agent_if_low(agent.wallet.address()) + + # Define dialogue messages; each transition needs a separate message + class InitiateChitChatDialogue(Model): + pass + + class AcceptChitChatDialogue(Model): + pass + + class ChitChatDialogueMessage(Model): + text: str + + class ConcludeChitChatDialogue(Model): + pass + + class RejectChitChatDialogue(Model): + pass + + # Instantiate the dialogues + chitchat_dialogue = ChitChatDialogue( + version="0.1", + agent_address=agent.address, + ) + + # Get an overview of the dialogue structure + print("Dialogue overview:") + print(json.dumps(chitchat_dialogue.get_overview(), indent=4)) + print("---") + + @chitchat_dialogue.on_initiate_session(InitiateChitChatDialogue) + async def start_chitchat( + ctx: Context, + sender: str, + _msg: InitiateChitChatDialogue, + ): + ctx.logger.info(f"Received init message from {sender}") + # Do something when the dialogue is initiated + await ctx.send(sender, AcceptChitChatDialogue()) + + @chitchat_dialogue.on_start_dialogue(AcceptChitChatDialogue) + async def accept_chitchat( + ctx: Context, + sender: str, + _msg: AcceptChitChatDialogue, + ): + ctx.logger.info( + f"session with {sender} was accepted. I'll say 'Hello!' to start the ChitChat" + ) + # Do something after the dialogue is started; e.g. send a message + await ctx.send(sender, ChitChatDialogueMessage(text="Hello!")) + + @chitchat_dialogue.on_reject_session(RejectChitChatDialogue) + async def reject_chitchat( + ctx: Context, + sender: str, + _msg: RejectChitChatDialogue, + ): + # Do something when the dialogue is rejected and nothing has been sent yet + ctx.logger.info(f"Received reject message from: {sender}") + + @chitchat_dialogue.on_continue_dialogue(ChitChatDialogueMessage) + async def continue_chitchat( + ctx: Context, + sender: str, + msg: ChitChatDialogueMessage, + ): + # Do something when the dialogue continues + ctx.logger.info(f"Received message: {msg.text}") + try: + my_msg = input("Please enter your message:\n> ") + if my_msg != "exit": + await ctx.send(sender, ChitChatDialogueMessage(text=my_msg)) + else: + await ctx.send(sender, ConcludeChitChatDialogue()) + ctx.logger.info( + f"Received conclude message from: {sender}; accessing history:" + ) + ctx.logger.info(chitchat_dialogue.get_conversation(ctx.session)) + except EOFError: + await ctx.send(sender, ConcludeChitChatDialogue()) + + @chitchat_dialogue.on_end_session(ConcludeChitChatDialogue) + async def conclude_chitchat( + ctx: Context, + sender: str, + _msg: ConcludeChitChatDialogue, + ): + # Do something when the dialogue is concluded after messages have been exchanged + ctx.logger.info(f"Received conclude message from: {sender}; accessing history:") + ctx.logger.info(chitchat_dialogue.get_conversation(ctx.session)) + + agent.include(chitchat_dialogue) + + if __name__ == "__main__": + print(f"Agent address: {agent.address}") + agent.run() + +``` + + - Create Python `agent2.py` script: @@ -369,127 +449,138 @@ The contents of this script are to be shared between the agents that want to use - - - - ```python copy filename="agent2.py" - """Chit chat dialogue example""" - - from asyncio import sleep - - from uagents import Agent, Context, Model - from uagents.setup import fund_agent_if_low - from dialogues.chitchat import ChitChatDialogue - - CHIT_AGENT_ADDRESS = "" - - agent = Agent( - name="chat_agent", - seed="", - port=8002, - endpoint="http://127.0.0.1:8002/submit", - ) - - fund_agent_if_low(agent.wallet.address()) - - # Define dialogue messages; each transition needs a separate message - class InitiateChitChatDialogue(Model): - pass - - class AcceptChitChatDialogue(Model): - pass - - class ChitChatDialogueMessage(Model): - text: str - - class ConcludeChitChatDialogue(Model): - pass - - class RejectChitChatDialogue(Model): - pass - - # Instantiate the dialogues - chitchat_dialogue = ChitChatDialogue( - version="0.1", - agent_address=agent.address, - ) - - @chitchat_dialogue.on_initiate_session(InitiateChitChatDialogue) - async def start_chitchat( - ctx: Context, - sender: str, - _msg: InitiateChitChatDialogue, - ): - ctx.logger.info(f"Received init message from {sender}") - # Do something when the dialogue is initiated - await ctx.send(sender, AcceptChitChatDialogue()) - - @chitchat_dialogue.on_start_dialogue(AcceptChitChatDialogue) - async def accept_chitchat( - ctx: Context, - sender: str, - _msg: AcceptChitChatDialogue, - ): - ctx.logger.info( - f"session with {sender} was accepted. I'll say 'Hello!' to start the ChitChat" - ) - # Do something after the dialogue is started; e.g. send a message - await ctx.send(sender, ChitChatDialogueMessage(text="Hello!")) - - @chitchat_dialogue.on_reject_session(RejectChitChatDialogue) - async def reject_chitchat( - ctx: Context, - sender: str, - _msg: RejectChitChatDialogue, - ): - # Do something when the dialogue is rejected and nothing has been sent yet - ctx.logger.info(f"Received reject message from: {sender}") - - @chitchat_dialogue.on_continue_dialogue(ChitChatDialogueMessage) - async def continue_chitchat( - ctx: Context, - sender: str, - msg: ChitChatDialogueMessage, - ): - ctx.logger.info(f"Received message: {msg.text}") - try: - my_msg = input("Please enter your message:\n> ") - if my_msg != "exit": - await ctx.send(sender, ChitChatDialogueMessage(text=my_msg)) - else: - await ctx.send(sender, ConcludeChitChatDialogue()) - ctx.logger.info( - f"Received conclude message from: {sender}; accessing history:" - ) - ctx.logger.info(chitchat_dialogue.get_conversation(ctx.session)) - except EOFError: - await ctx.send(sender, ConcludeChitChatDialogue()) - - @chitchat_dialogue.on_end_session(ConcludeChitChatDialogue) - async def conclude_chitchat( - ctx: Context, - sender: str, - _msg: ConcludeChitChatDialogue, - ): - # Do something when the dialogue is concluded after messages have been exchanged - ctx.logger.info(f"Received conclude message from: {sender}; accessing history:") - ctx.logger.info(chitchat_dialogue.get_conversation(ctx.session)) - - agent.include(chitchat_dialogue) - - # Initiate dialogue by sending message to agent1 - @agent.on_event("startup") - async def start_cycle(ctx: Context): - await sleep(5) - await chitchat_dialogue.start_dialogue( - ctx, CHIT_AGENT_ADDRESS, InitiateChitChatDialogue() - ) - - if __name__ == "__main__": - print(f"Agent address: {agent.address}") - agent.run() - ``` - + + + + + + + ```py copy filename="agent2.py" + + """Chit chat dialogue example""" + + from asyncio import sleep + + from uagents import Agent, Context, Model + from uagents.setup import fund_agent_if_low + from dialogues.chitchat import ChitChatDialogue + + CHIT_AGENT_ADDRESS = "" + + agent = Agent( + name="chat_agent", + seed="", + port=8002, + endpoint="http://127.0.0.1:8002/submit", + ) + + fund_agent_if_low(agent.wallet.address()) + + # Define dialogue messages; each transition needs a separate message + class InitiateChitChatDialogue(Model): + pass + + class AcceptChitChatDialogue(Model): + pass + + class ChitChatDialogueMessage(Model): + text: str + + class ConcludeChitChatDialogue(Model): + pass + + class RejectChitChatDialogue(Model): + pass + + # Instantiate the dialogues + chitchat_dialogue = ChitChatDialogue( + version="0.1", + agent_address=agent.address, + ) + + @chitchat_dialogue.on_initiate_session(InitiateChitChatDialogue) + async def start_chitchat( + ctx: Context, + sender: str, + _msg: InitiateChitChatDialogue, + ): + ctx.logger.info(f"Received init message from {sender}") + # Do something when the dialogue is initiated + await ctx.send(sender, AcceptChitChatDialogue()) + + @chitchat_dialogue.on_start_dialogue(AcceptChitChatDialogue) + async def accept_chitchat( + ctx: Context, + sender: str, + _msg: AcceptChitChatDialogue, + ): + ctx.logger.info( + f"session with {sender} was accepted. I'll say 'Hello!' to start the ChitChat" + ) + # Do something after the dialogue is started; e.g. send a message + await ctx.send(sender, ChitChatDialogueMessage(text="Hello!")) + + @chitchat_dialogue.on_reject_session(RejectChitChatDialogue) + async def reject_chitchat( + ctx: Context, + sender: str, + _msg: RejectChitChatDialogue, + ): + # Do something when the dialogue is rejected and nothing has been sent yet + ctx.logger.info(f"Received reject message from: {sender}") + + @chitchat_dialogue.on_continue_dialogue(ChitChatDialogueMessage) + async def continue_chitchat( + ctx: Context, + sender: str, + msg: ChitChatDialogueMessage, + ): + ctx.logger.info(f"Received message: {msg.text}") + try: + my_msg = input("Please enter your message:\n> ") + if my_msg != "exit": + await ctx.send(sender, ChitChatDialogueMessage(text=my_msg)) + else: + await ctx.send(sender, ConcludeChitChatDialogue()) + ctx.logger.info( + f"Received conclude message from: {sender}; accessing history:" + ) + ctx.logger.info(chitchat_dialogue.get_conversation(ctx.session)) + except EOFError: + await ctx.send(sender, ConcludeChitChatDialogue()) + + @chitchat_dialogue.on_end_session(ConcludeChitChatDialogue) + async def conclude_chitchat( + ctx: Context, + sender: str, + _msg: ConcludeChitChatDialogue, + ): + # Do something when the dialogue is concluded after messages have been exchanged + ctx.logger.info(f"Received conclude message from: {sender}; accessing history:") + ctx.logger.info(chitchat_dialogue.get_conversation(ctx.session)) + + agent.include(chitchat_dialogue) + + # Initiate dialogue by sending message to agent1 + @agent.on_event("startup") + async def start_cycle(ctx: Context): + await sleep(5) + await chitchat_dialogue.start_dialogue( + ctx, CHIT_AGENT_ADDRESS, InitiateChitChatDialogue() + ) + + if __name__ == "__main__": + print(f"Agent address: {agent.address}") + agent.run() + +``` + + Remember to update the agent's address to communicate to each other and seed phrase of own choice. diff --git a/pages/examples/advanced/predefined-dialogue-chitchat.mdx b/pages/examples/advanced/predefined-dialogue-chitchat.mdx index 7d1dac935..125acb667 100644 --- a/pages/examples/advanced/predefined-dialogue-chitchat.mdx +++ b/pages/examples/advanced/predefined-dialogue-chitchat.mdx @@ -1,5 +1,5 @@ import { Callout } from 'nextra/components' -import { CodeGroup, DocsCode } from "../../../components/code"; +import { CodeGroup, DocsCode, CodeSegment, GithubCodeSegment } from "../../../components/code"; # Predefined Dialogue Chit-Chat @@ -7,6 +7,8 @@ import { CodeGroup, DocsCode } from "../../../components/code"; This example illustrates an automated dialogue scenario using a hardcoded dialogue management system between two agents. The dialogue flow is predefined, minimizing the need for manual intervention or dynamic decision-making during the dialogue process. +Please check out the example code in our [examples repo ↗️](https://github.com/fetchai/uAgent-Examples/tree/main/1-uagents/examples/advanced/predefined-dialogue-chitchat) to run this locally. + ### Guide - [How to use Dialogues ↗️](/guides/agents/dialogues) @@ -47,190 +49,310 @@ This example illustrates an automated dialogue scenario using a hardcoded dialog - Import required libraries. - ```python - from typing import Type - from warnings import warn - from uagents import Model - from uagents.context import Context - from uagents.experimental.dialogues import Dialogue, Edge, Node - ``` - -- Define dialogue message models, each transition needs a separate message. - - ```python - # define dialogue messages; each transition needs a separate message - class InitiateChitChatDialogue(Model): - pass + + + + + + + ```py copy filename="hardcoded_chitchat.py" + + from typing import Type + from warnings import warn + from uagents import Model + from uagents.context import Context + from uagents.experimental.dialogues import Dialogue, Edge, Node + + +``` + - class AcceptChitChatDialogue(Model): - pass + - class ChitChatDialogueMessage(Model): - text: str +- Define dialogue message models, each transition needs a separate message. - class ConcludeChitChatDialogue(Model): - pass + + + + + + + ```py copy filename="hardcoded_chitchat.py" + + # define dialogue messages; each transition needs a separate message + class InitiateChitChatDialogue(Model): + pass + + class AcceptChitChatDialogue(Model): + pass + + class ChitChatDialogueMessage(Model): + text: str + + class ConcludeChitChatDialogue(Model): + pass + + class RejectChitChatDialogue(Model): + pass + + +``` + - class RejectChitChatDialogue(Model): - pass - ``` + - Define `nodes` (state) of dialogues like default, initiate, chitchat and end state. - ```python - # Node definition for the dialogue states - default_state = Node( - name="Default State", - description=( - "This is the default state of the dialogue. Every session starts in " - "this state and is automatically updated once ." - ), - initial=True, - ) - - # Currently not used as states are measured by the edges - init_state = Node( - name="Initiated", - description=( - "This is the initial state of the dialogue that is only available at " - "the receiving agent." - ) - ) - - chatting_state = Node( - name="Chit Chatting", - description="This is the state in which messages are exchanged.", - ) - - end_state = Node( - name="Concluded", - description="This is the state after the dialogue has been concluded.", - ) - ``` + + + + + + + ```py copy filename="hardcoded_chitchat.py" + + # Node definition for the dialogue states + default_state = Node( + name="Default State", + description=( + "This is the default state of the dialogue. Every session starts in " + "this state and is automatically updated once ." + ), + initial=True, + ) + + # Currently not used as states are measured by the edges + init_state = Node( + name="Initiated", + description=( + "This is the initial state of the dialogue that is only available at " + "the receiving agent." + ) + ) + + chatting_state = Node( + name="Chit Chatting", + description="This is the state in which messages are exchanged.", + ) + + end_state = Node( + name="Concluded", + description="This is the state after the dialogue has been concluded.", + ) + + +``` + + + - Define `edges` (transition) of dialogues like initiate session, start dialogue, continue dialogue and end session. - ```python - # Edge definition for the dialogue transitions - init_session = Edge( - name="initiate_session", - description="Every dialogue starts with this transition.", - parent=None, - child=init_state, - ) - - start_dialogue = Edge( - name="start_dialogue", - description="This is the transition from initiated to chit chatting.", - parent=init_state, - child=chatting_state, - ) - - cont_dialogue = Edge( - name="continue_dialogue", - description=( - "This is the transition from one dialogue message to the next, " - "i.e. for when the dialogue continues." - ), - parent=chatting_state, - child=chatting_state, - ) - - end_session = Edge( - name="end_session", - description="This is the transition for when the session is ended.", - parent=chatting_state, - child=end_state, - ) - ``` + + + + + + + ```py copy filename="hardcoded_chitchat.py" + + # Edge definition for the dialogue transitions + init_session = Edge( + name="initiate_session", + description="Every dialogue starts with this transition.", + parent=None, + child=init_state, + ) + + start_dialogue = Edge( + name="start_dialogue", + description="This is the transition from initiated to chit chatting.", + parent=init_state, + child=chatting_state, + ) + + cont_dialogue = Edge( + name="continue_dialogue", + description=( + "This is the transition from one dialogue message to the next, " + "i.e. for when the dialogue continues." + ), + parent=chatting_state, + child=chatting_state, + ) + + end_session = Edge( + name="end_session", + description="This is the transition for when the session is ended.", + parent=chatting_state, + child=end_state, + ) + + +``` + + + - Define default behaviour for individual dialogue edges. Only the interaction that requires input from the user is exposed, making the other parts of the dialogue more robust and easier to maintain. - ```python - async def start_chitchat(ctx: Context,sender: str,_msg: Type[Model]): - ctx.logger.info(f"Received init message from {sender}. Accepting Dialogue.") - await ctx.send(sender, AcceptChitChatDialogue()) - - async def accept_chitchat(ctx: Context,sender: str,_msg: Type[Model],): - ctx.logger.info( - f"Dialogue session with {sender} was accepted. " - "I'll say 'Hello!' to start the ChitChat" - ) - await ctx.send(sender, ChitChatDialogueMessage(text="Hello!")) - - async def conclude_chitchat(ctx: Context,sender: str,_msg: Type[Model],): - ctx.logger.info(f"Received conclude message from: {sender}; accessing history:") - ctx.logger.info(ctx.dialogue) - - async def default(_ctx: Context,_sender: str,_msg: Type[Model],): - warn( - "There is no handler for this message, please add your own logic by " - "using the `on_continue_dialogue` decorator.", - RuntimeWarning, - stacklevel=2, - ) - - async def persisting_function(ctx: Context,_sender: str,_msg: Type[Model],): - ctx.logger.info("I was not overwritten, hehe.") - ``` + + + + + + + ```py copy filename="hardcoded_chitchat.py" + + + async def start_chitchat(ctx: Context,sender: str,_msg: Type[Model]): + ctx.logger.info(f"Received init message from {sender}. Accepting Dialogue.") + await ctx.send(sender, AcceptChitChatDialogue()) + + async def accept_chitchat(ctx: Context,sender: str,_msg: Type[Model],): + ctx.logger.info( + f"Dialogue session with {sender} was accepted. " + "I'll say 'Hello!' to start the ChitChat" + ) + await ctx.send(sender, ChitChatDialogueMessage(text="Hello!")) + + async def conclude_chitchat(ctx: Context,sender: str,_msg: Type[Model],): + ctx.logger.info(f"Received conclude message from: {sender}; accessing history:") + ctx.logger.info(ctx.dialogue) + + async def default(_ctx: Context,_sender: str,_msg: Type[Model],): + warn( + "There is no handler for this message, please add your own logic by " + "using the `on_continue_dialogue` decorator.", + RuntimeWarning, + stacklevel=2, + ) + + async def persisting_function(ctx: Context,_sender: str,_msg: Type[Model],): + ctx.logger.info("I was not overwritten, hehe.") + + +``` + + + - In the provided code, specific message types associated with different dialogue states trigger predefined functions that manage the flow and actions of the dialogue, automating the transition between states and handling interactions within the dialogue system efficiently. - ```python - init_session.set_message_handler(InitiateChitChatDialogue, start_chitchat) - start_dialogue.set_message_handler(AcceptChitChatDialogue, accept_chitchat) - cont_dialogue.set_message_handler(ChitChatDialogueMessage, default) - cont_dialogue.set_edge_handler(ChitChatDialogueMessage, persisting_function) - end_session.set_message_handler(ConcludeChitChatDialogue, conclude_chitchat) - ``` + + + + + + + ```py copy filename="hardcoded_chitchat.py" + + + + init_session.set_message_handler(InitiateChitChatDialogue, start_chitchat) + start_dialogue.set_message_handler(AcceptChitChatDialogue, accept_chitchat) + cont_dialogue.set_message_handler(ChitChatDialogueMessage, default) + cont_dialogue.set_edge_handler(ChitChatDialogueMessage, persisting_function) + end_session.set_message_handler(ConcludeChitChatDialogue, conclude_chitchat) + + +``` + + + - Define `ChitChatDialogue` class and include nodes and edges into it. These acts as rule for chit chat dialogues. - ```python - class ChitChatDialogue(Dialogue): - """ - This is the specific definition of the rules for the chit-chat dialogue - The rules will be predefined and the actual messages will be passed into it. - - In this specific instance of the ChitChatDialogue, some parts of the dialogue - are hardcoded, such as the initial message and the response to it. - This is done to demonstrate that the dialogue can be defined in a way for - developers to only focus on the parts that are relevant to them. - """ - def __init__( - self, - version: str | None = None, - agent_address: str | None = None, - ) -> None: - super().__init__( - name="ChitChatDialogue", - version=version, - agent_address=agent_address, - nodes=[ - init_state, - chatting_state, - end_state, - ], - edges=[ - init_session, - start_dialogue, - cont_dialogue, - end_session, - ], - ) - - def on_continue_dialogue(self): - """ - This handler is triggered for every incoming "chitchat" message - once the session has been accepted. - Any additional stateful information within a dialogue needs to be - persisted explicitly to access it at a later point in the dialogue. - """ - return super()._on_state_transition( - cont_dialogue.name, - ChitChatDialogueMessage, - ) - ``` + + + + + + + ```py copy filename="hardcoded_chitchat.py" + + + class ChitChatDialogue(Dialogue): + """ + This is the specific definition of the rules for the chit-chat dialogue + The rules will be predefined and the actual messages will be passed into it. + + In this specific instance of the ChitChatDialogue, some parts of the dialogue + are hardcoded, such as the initial message and the response to it. + This is done to demonstrate that the dialogue can be defined in a way for + developers to only focus on the parts that are relevant to them. + """ + def __init__( + self, + version: str | None = None, + ) -> None: + super().__init__( + name="ChitChatDialogue", + version=version, + nodes=[ + init_state, + chatting_state, + end_state, + ], + edges=[ + init_session, + start_dialogue, + cont_dialogue, + end_session, + ], + ) + + def on_continue_dialogue(self): + """ + This handler is triggered for every incoming "chitchat" message + once the session has been accepted. + Any additional stateful information within a dialogue needs to be + persisted explicitly to access it at a later point in the dialogue. + """ + return super()._on_state_transition( + cont_dialogue.name, + ChitChatDialogueMessage, + ) + +``` + + + Include all the above mentioned script sections into a single script and save it as `hardcoded_chitchat.py` @@ -245,65 +367,75 @@ These two agents use the `hardcoded_chitchat` dialogue system to automate the in - Navigate to your working directory and create a Python script named `agent1.py`. - Copy the following script into `agent1.py`: - - - - ```python copy filename="agent1.py" - # Import required libraries - import json - - from uagents import Agent - from uagents.context import Context - - from dialogues.hardcoded_chitchat import (ChitChatDialogue, - ChitChatDialogueMessage, - ConcludeChitChatDialogue) - - CHAT_AGENT_ADDRESS = "" - - agent = Agent( - name="chit_agent", - seed="", - port=8001, - endpoint="http://127.0.0.1:8001/submit", - ) - - # Instantiate the dialogues - chitchat_dialogue = ChitChatDialogue( - version="0.1", - storage=agent.storage, - ) - - # Get an overview of the dialogue structure - print("Dialogue overview:") - print(json.dumps(chitchat_dialogue.get_overview(), indent=4)) - print("---") - - # This is the only decorator that is needed to add to your agent with the - # hardcoded dialogue example. If you omit this decorator, the dialogue will - # emit a warning. - @chitchat_dialogue.on_continue_dialogue() - async def continue_chitchat( - ctx: Context, - sender: str, - msg: ChitChatDialogueMessage, - ): - # Do something when the dialogue continues - ctx.logger.info(f"Received message: {msg.text}") - try: - my_msg = input("Please enter your message:\n> ") - await ctx.send(sender, ChitChatDialogueMessage(text=my_msg)) - except EOFError: - await ctx.send(sender, ConcludeChitChatDialogue()) - - agent.include(chitchat_dialogue) # Including dialogue in agent - - if __name__ == "__main__": - print(f"Agent address: {agent.address}") - agent.run() # Running agent - - ``` - + + + + + + + ```py copy filename="agent1.py" + + # Import required libraries + import json + + from uagents import Agent + from uagents.context import Context + + from dialogues.hardcoded_chitchat import (ChitChatDialogue, + ChitChatDialogueMessage, + ConcludeChitChatDialogue) + + CHAT_AGENT_ADDRESS = "" + + agent = Agent( + name="chit_agent", + seed="", + port=8001, + endpoint="http://127.0.0.1:8001/submit", + ) + + # Instantiate the dialogues + chitchat_dialogue = ChitChatDialogue( + version="0.1", + ) + + # Get an overview of the dialogue structure + print("Dialogue overview:") + print(json.dumps(chitchat_dialogue.get_overview(), indent=4)) + print("---") + + # This is the only decorator that is needed to add to your agent with the + # hardcoded dialogue example. If you omit this decorator, the dialogue will + # emit a warning. + @chitchat_dialogue.on_continue_dialogue() + async def continue_chitchat( + ctx: Context, + sender: str, + msg: ChitChatDialogueMessage, + ): + # Do something when the dialogue continues + ctx.logger.info(f"Received message: {msg.text}") + try: + my_msg = input("Please enter your message:\n> ") + await ctx.send(sender, ChitChatDialogueMessage(text=my_msg)) + except EOFError: + await ctx.send(sender, ConcludeChitChatDialogue()) + + agent.include(chitchat_dialogue) # Including dialogue in agent + + if __name__ == "__main__": + print(f"Agent address: {agent.address}") + agent.run() # Running agent + + +``` + + ### Setting up `agent2` @@ -312,65 +444,75 @@ These two agents use the `hardcoded_chitchat` dialogue system to automate the in - Create a new Python script named `agent2.py` in the same directory. - Paste the following code into `agent2.py`: - - - ```python copy filename="agent2.py" - """Chit chat dialogue example""" - - from asyncio import sleep - - from uagents import Agent, Context - - from dialogues.hardcoded_chitchat import (ChitChatDialogue, - ChitChatDialogueMessage, - InitiateChitChatDialogue) - - CHIT_AGENT_ADDRESS = "" - - agent = Agent( - name="chat_agent", - seed="", - port=8002, - endpoint="http://127.0.0.1:8002/submit", - ) - - # Instantiate the dialogues - chitchat_dialogue = ChitChatDialogue( - version="0.1", - storage=agent.storage, - ) - - @chitchat_dialogue.on_continue_dialogue() - async def continue_chitchat( - ctx: Context, - sender: str, - msg: ChitChatDialogueMessage, - ): - ctx.logger.info(f"Returning: {msg.text}") - await ctx.send(sender, ChitChatDialogueMessage(text=msg.text)) - - # Initiate dialogue after 5 seconds - @agent.on_event("startup") - async def start_cycle(ctx: Context): - await sleep(5) - await chitchat_dialogue.start_dialogue( - ctx, CHIT_AGENT_ADDRESS, InitiateChitChatDialogue() - ) - - agent.include(chitchat_dialogue) - - if __name__ == "__main__": - print(f"Agent address: {agent.address}") - agent.run() - ``` - - - - Remember to update the agent's address to communicate to each other and seed phrase of own choice. - + + + + + + + ```py copy filename="agent2.py" + + """Chit chat dialogue example""" + + from asyncio import sleep + + from uagents import Agent, Context + + from dialogues.hardcoded_chitchat import (ChitChatDialogue, + ChitChatDialogueMessage, + InitiateChitChatDialogue) + + CHIT_AGENT_ADDRESS = "" + + agent = Agent( + name="chat_agent", + seed="", + port=8002, + endpoint="http://127.0.0.1:8002/submit", + ) + + # Instantiate the dialogues + chitchat_dialogue = ChitChatDialogue( + version="0.1", + ) + + @chitchat_dialogue.on_continue_dialogue() + async def continue_chitchat( + ctx: Context, + sender: str, + msg: ChitChatDialogueMessage, + ): + ctx.logger.info(f"Returning: {msg.text}") + await ctx.send(sender, ChitChatDialogueMessage(text=msg.text)) + + # Initiate dialogue after 5 seconds + @agent.on_event("startup") + async def start_cycle(ctx: Context): + await sleep(5) + await chitchat_dialogue.start_dialogue( + ctx, CHIT_AGENT_ADDRESS, InitiateChitChatDialogue() + ) + + agent.include(chitchat_dialogue) + + if __name__ == "__main__": + print(f"Agent address: {agent.address}") + agent.run() + +``` + + + Remember to update the agent's address to communicate to each other and seed phrase of own choice. + + ## Step 3: Run the Dialogue - Start `agent1`: