-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add examples for the intermediate topics (#20)
- Loading branch information
1 parent
0c20514
commit 5a4a5ef
Showing
48 changed files
with
2,421 additions
and
0 deletions.
There are no files selected for viewing
63 changes: 63 additions & 0 deletions
63
1-uagents/examples/intermediate/agent-and-function-api/agent.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
from uagents import Agent, Bureau, Context, Model | ||
from uagents.setup import fund_agent_if_low | ||
import requests | ||
from ai_engine import UAgentResponse, UAgentResponseType | ||
|
||
|
||
class Coordinates(Model): | ||
location: str | ||
|
||
|
||
# First generate a secure seed phrase (e.g. https://pypi.org/project/mnemonic/) | ||
SEED_PHRASE = "put_your_seed_phrase_here" | ||
|
||
# Now go to https://agentverse.ai, register your agent in the Mailroom by providing the address you just copied. | ||
# Then, copy the agent's mailbox key and insert it here below inline | ||
AGENT_MAILBOX_KEY = "put_your_AGENT_MAILBOX_KEY_here" | ||
|
||
# Now your agent is ready to join the agentverse! | ||
location_agent = Agent( | ||
name="location_agent", | ||
seed=SEED_PHRASE, | ||
mailbox=f"{AGENT_MAILBOX_KEY}@https://agentverse.ai", | ||
) | ||
|
||
fund_agent_if_low(location_agent.wallet.address()) | ||
|
||
# Copy the address shown below | ||
print(f"Your agent's address is: {location_agent.address}") | ||
|
||
location_protocol = Protocol("Location Coordinates") | ||
|
||
|
||
async def location_coordinates(latitude, longitude): | ||
url = "https://geocoding-by-api-ninjas.p.rapidapi.com/v1/reversegeocoding" | ||
querystring = {"lat": latitude, "lon": longitude} | ||
|
||
headers = { | ||
"X-RapidAPI-Key": "YOUR_API_KEY", | ||
"X-RapidAPI-Host": "geocoding-by-api-ninjas.p.rapidapi.com", | ||
} | ||
|
||
response = requests.get(url, headers=headers, params=querystring) | ||
|
||
data = response.json()[0]["name"] | ||
|
||
return data | ||
|
||
|
||
@location_protocol.on_message(model=Coordinates, replies=UAgentResponse) | ||
async def location_coordinates_calculator(ctx: Context, sender: str, msg: Coordinates): | ||
ctx.logger.info(msg.location) | ||
latitude, longitude = map(str.strip, msg.location.split(",")) | ||
city = location_coordinates(latitude, longitude) | ||
ctx.logger.info(city) | ||
message = city | ||
await ctx.send( | ||
sender, UAgentResponse(message=message, type=UAgentResponseType.FINAL) | ||
) | ||
|
||
|
||
location_agent.include(location_protocol) | ||
|
||
location_agent.run() |
109 changes: 109 additions & 0 deletions
109
1-uagents/examples/intermediate/agent-and-function-api/agent_create.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
# Importing Required libraries | ||
import time | ||
import requests | ||
|
||
# Decode the refresh token | ||
token = f'Bearer <Your_access_token>' | ||
|
||
# Take name of agent from user | ||
name = input("Please give name of your agent? ") | ||
# Create payload for agent creation request | ||
agent_creation_data = {"name": name} | ||
# Post request to create an agent and store address | ||
response_agent = requests.post( | ||
"https://agentverse.ai/v1/hosting/agents", | ||
json=agent_creation_data, | ||
headers={"Authorization": token}, | ||
).json() | ||
|
||
address = response_agent["address"] | ||
print(f"Agent Address : {address}") | ||
|
||
# Reading code to be placed in agent | ||
with open("agent.py", "r") as file: | ||
code = file.read() | ||
agent_code_data = {"code": code} | ||
|
||
# Creating agent.py script for created agent | ||
response_code_update = requests.put( | ||
f"https://agentverse.ai/v1/hosting/agents/{address}/code", | ||
json=agent_code_data, | ||
headers={"Authorization": token}, | ||
) | ||
|
||
# Starting the agent | ||
requests.post( | ||
f"https://agentverse.ai/v1/hosting/agents/{address}/start", | ||
headers={"Authorization": token}, | ||
) | ||
time.sleep(10) # waiting before getting agent's protocol | ||
|
||
# Request to get agent protocol digest | ||
response_protcol = requests.get( | ||
f"https://agentverse.ai/v1/almanac/agents/{address}", | ||
headers={"Authorization": token}, | ||
) | ||
protocol_digest = response_protcol.json()["protocols"][1] | ||
print(f"Protocol Digest : {protocol_digest}") | ||
time.sleep(10) # Waiting before getting model_digest | ||
|
||
# Request to get agent's model details | ||
response_model = requests.get( | ||
f"https://agentverse.ai/v1/almanac/manifests/protocols/{protocol_digest}", | ||
headers={"Authorization": token}, | ||
) | ||
model = response_model.json()["models"] | ||
time.sleep(10) # Waiting before storing details to create functions | ||
|
||
function_group_ids = requests.get( | ||
"https://agentverse.ai/v1beta1/function-groups/", headers={"Authorization": token} | ||
) | ||
function_group_id = function_group_ids.json()[0]["uuid"] | ||
time.sleep(10) | ||
|
||
# Taking inputs from user for details required to create a function | ||
name_service = input("Please give function name: ") | ||
description = input("Please enter function description: ") | ||
field_name = input("Please enter field name: ") | ||
field_description = input("Please enter field description: ") | ||
tasktype = input("Please tell primary or secondary function: ").upper() | ||
|
||
# Logging details provided by user | ||
print( | ||
f"Service name: {name_service} \nFunction Description: {description} \nField Name: {field_name}\nField Description: {field_description}\nTask Type: {tasktype}" | ||
) | ||
|
||
# Storing model digest and name to be used for function creation | ||
model_digest = response_model.json()["interactions"][0]["request"].replace("model:", "") | ||
print(f"Model Digest : {model_digest}") | ||
model_name = model[0]["schema"]["title"] | ||
print(f"Model Name : {model_name}") | ||
|
||
# Creating payload for function creation | ||
data = { | ||
"agent": address, | ||
"name": name_service, | ||
"description": description, | ||
"protocolDigest": protocol_digest, | ||
"modelDigest": model_digest, | ||
"modelName": model_name, | ||
"arguments": [ | ||
{ | ||
"name": field_name, | ||
"required": True, | ||
"type": "string", | ||
"description": field_description, | ||
} | ||
], | ||
"type": tasktype, | ||
} | ||
|
||
# Requesting AI Engine function API to create a function with created payload and storing the response. | ||
response_function = requests.post( | ||
"https://agentverse.ai/v1beta1/functions/", | ||
json=data, | ||
headers={"Authorization": token}, | ||
) | ||
# Storing name of function and printing it to check if function was created successfully | ||
name = response_function.json()["name"] | ||
print(f"Function Created with name: {name}") |
27 changes: 27 additions & 0 deletions
27
1-uagents/examples/intermediate/agent-secret-api/agent-secret.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# Importing libraries | ||
import requests | ||
|
||
# Decode the refresh token | ||
token = 'Bearer fauna_access_token' | ||
|
||
# Take name of agent and secret details from user | ||
address = input('Please enter address of agent to which you want to add the secret: ') | ||
name = input("Please enter name for your secret: ") | ||
secret = input("Please enter value for your secret: ") | ||
|
||
# Create Payload for post request | ||
data = { | ||
'address': address, | ||
'name': name, | ||
'secret': secret | ||
} | ||
|
||
# Post request to add secret to agent | ||
response_agent = requests.post("https://agentverse.ai/v1/hosting/secrets", json=data, headers={"Authorization": token}) | ||
|
||
|
||
# Check if the response code is 200 | ||
if response_agent.status_code == 200: | ||
print("Secret added successfully.") | ||
else: | ||
print(f"Failed to add secret. Status code: {response_agent.status_code}") |
51 changes: 51 additions & 0 deletions
51
1-uagents/examples/intermediate/agents-cleaning-demo/cleaner.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
from datetime import datetime | ||
|
||
from protocols.cleaning import cleaning_proto | ||
from protocols.cleaning.models import Availability, Provider, Service, ServiceType | ||
from pytz import utc | ||
from tortoise import Tortoise | ||
from uagents import Agent, Context | ||
|
||
cleaner = Agent( | ||
name="cleaner", | ||
port=8001, | ||
seed="cleaner secret phrase", | ||
endpoint={ | ||
"http://127.0.0.1:8001/submit": {}, | ||
}, | ||
) | ||
|
||
# build the cleaning service agent from the cleaning protocol | ||
cleaner.include(cleaning_proto) | ||
|
||
@cleaner.on_event("startup") | ||
async def startup(_ctx: Context): | ||
await Tortoise.init( | ||
db_url="sqlite://db.sqlite3", modules={"models": ["protocols.cleaning.models"]} | ||
) | ||
await Tortoise.generate_schemas() | ||
|
||
provider = await Provider.create(name=cleaner.name, location="London Kings Cross") | ||
|
||
floor = await Service.create(type=ServiceType.FLOOR) | ||
window = await Service.create(type=ServiceType.WINDOW) | ||
laundry = await Service.create(type=ServiceType.LAUNDRY) | ||
|
||
await provider.services.add(floor) | ||
await provider.services.add(window) | ||
await provider.services.add(laundry) | ||
|
||
await Availability.create( | ||
provider=provider, | ||
time_start=utc.localize(datetime.fromisoformat("2022-01-31 00:00:00")), | ||
time_end=utc.localize(datetime.fromisoformat("2023-05-01 00:00:00")), | ||
max_distance=10, | ||
min_hourly_price=5, | ||
) | ||
|
||
@cleaner.on_event("shutdown") | ||
async def shutdown(_ctx: Context): | ||
await Tortoise.close_connections() | ||
|
||
if __name__ == "__main__": | ||
cleaner.run() |
Empty file.
119 changes: 119 additions & 0 deletions
119
1-uagents/examples/intermediate/agents-cleaning-demo/protocols/cleaning/__init__.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
from datetime import datetime, timedelta | ||
from typing import List | ||
|
||
from geopy.distance import geodesic | ||
from geopy.geocoders import Nominatim | ||
|
||
from uagents import Context, Model, Protocol | ||
|
||
from .models import Availability, Provider, User | ||
|
||
PROTOCOL_NAME = "cleaning" | ||
PROTOCOL_VERSION = "0.1.0" | ||
|
||
|
||
class ServiceRequest(Model): | ||
user: str | ||
location: str | ||
time_start: datetime | ||
duration: timedelta | ||
services: List[int] | ||
max_price: float | ||
|
||
|
||
class ServiceResponse(Model): | ||
accept: bool | ||
price: float | ||
|
||
|
||
class ServiceBooking(Model): | ||
location: str | ||
time_start: datetime | ||
duration: timedelta | ||
services: List[int] | ||
price: float | ||
|
||
|
||
class BookingResponse(Model): | ||
success: bool | ||
|
||
|
||
cleaning_proto = Protocol(name=PROTOCOL_NAME, version=PROTOCOL_VERSION) | ||
|
||
|
||
def in_service_region( | ||
location: str, availability: Availability, provider: Provider | ||
) -> bool: | ||
geolocator = Nominatim(user_agent="micro_agents") | ||
|
||
user_location = geolocator.geocode(location) | ||
cleaner_location = geolocator.geocode(provider.location) | ||
|
||
if user_location is None: | ||
raise RuntimeError(f"user location {location} not found") | ||
|
||
if cleaner_location is None: | ||
raise RuntimeError(f"provider location {provider.location} not found") | ||
|
||
cleaner_coordinates = (cleaner_location.latitude, cleaner_location.longitude) | ||
user_coordinates = (user_location.latitude, user_location.longitude) | ||
|
||
service_distance = geodesic(user_coordinates, cleaner_coordinates).miles | ||
in_range = service_distance <= availability.max_distance | ||
|
||
return in_range | ||
|
||
|
||
@cleaning_proto.on_message(model=ServiceRequest, replies=ServiceResponse) | ||
async def handle_query_request(ctx: Context, sender: str, msg: ServiceRequest): | ||
provider = await Provider.filter(name=ctx.agent.name).first() | ||
availability = await Availability.get(provider=provider) | ||
services = [int(service.type) for service in await provider.services] | ||
markup = provider.markup | ||
|
||
user, _ = await User.get_or_create(name=msg.user, address=sender) | ||
msg_duration_hours: float = msg.duration.total_seconds() / 3600 | ||
ctx.logger.info(f"Received service request from user `{user.name}`") | ||
|
||
if ( | ||
set(msg.services) <= set(services) | ||
and in_service_region(msg.location, availability, provider) | ||
and availability.time_start <= msg.time_start | ||
and availability.time_end >= msg.time_start + msg.duration | ||
and availability.min_hourly_price * msg_duration_hours < msg.max_price | ||
): | ||
accept = True | ||
price = markup * availability.min_hourly_price * msg_duration_hours | ||
ctx.logger.info(f"I am available! Proposing price: {price}.") | ||
else: | ||
accept = False | ||
price = 0 | ||
ctx.logger.info("I am not available. Declining request.") | ||
|
||
await ctx.send(sender, ServiceResponse(accept=accept, price=price)) | ||
|
||
|
||
@cleaning_proto.on_message(model=ServiceBooking, replies=BookingResponse) | ||
async def handle_book_request(ctx: Context, sender: str, msg: ServiceBooking): | ||
provider = await Provider.filter(name=ctx.agent.name).first() | ||
availability = await Availability.get(provider=provider) | ||
services = [int(service.type) for service in await provider.services] | ||
|
||
user = await User.get(address=sender) | ||
msg_duration_hours: float = msg.duration.total_seconds() / 3600 | ||
ctx.logger.info(f"Received booking request from user `{user.name}`") | ||
|
||
success = ( | ||
set(msg.services) <= set(services) | ||
and availability.time_start <= msg.time_start | ||
and availability.time_end >= msg.time_start + msg.duration | ||
and msg.price <= availability.min_hourly_price * msg_duration_hours | ||
) | ||
|
||
if success: | ||
availability.time_start = msg.time_start + msg.duration | ||
await availability.save() | ||
ctx.logger.info("Accepted task and updated availability.") | ||
|
||
# send the response | ||
await ctx.send(sender, BookingResponse(success=success)) |
Oops, something went wrong.