Skip to content

Commit

Permalink
feat: add examples for the intermediate topics (#20)
Browse files Browse the repository at this point in the history
  • Loading branch information
gautamgambhir97 authored Nov 21, 2024
1 parent 0c20514 commit 5a4a5ef
Show file tree
Hide file tree
Showing 48 changed files with 2,421 additions and 0 deletions.
63 changes: 63 additions & 0 deletions 1-uagents/examples/intermediate/agent-and-function-api/agent.py
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 1-uagents/examples/intermediate/agent-and-function-api/agent_create.py
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 1-uagents/examples/intermediate/agent-secret-api/agent-secret.py
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 1-uagents/examples/intermediate/agents-cleaning-demo/cleaner.py
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.
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))
Loading

0 comments on commit 5a4a5ef

Please sign in to comment.