Skip to content

Commit

Permalink
simple negotiation example
Browse files Browse the repository at this point in the history
  • Loading branch information
ejfitzgerald committed Feb 26, 2024
1 parent bfca68b commit a02502a
Show file tree
Hide file tree
Showing 7 changed files with 1,482 additions and 0 deletions.
11 changes: 11 additions & 0 deletions integrations/agent-negotiation/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from uagents import Bureau

from negotiation.bob import bob
from negotiation.alice import alice

bureau = Bureau()
bureau.add(alice)
bureau.add(bob)

if __name__ == '__main__':
bureau.run()
Empty file.
61 changes: 61 additions & 0 deletions integrations/agent-negotiation/negotiation/alice.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
from uuid import uuid4

from uagents import Agent, Context

from negotiation.messages import CounterProposal, Acceptance, Reject, Proposal

ALICE_TARGET_MIN_PRICE = 60.0
ALICE_TARGET_MAX_PRICE = 110.0
ALICE_TARGET_ITEM = 'widget'

alice = Agent(name='alice', seed='alices super secret seed phrase')
print('Alice address: ', alice.address)

bob_address = 'agent1qg5a9zvex0gy2amagpvadp6f9kcf8jxa3akrqd09lf8kk2frlxj7q7pu3yt'



@alice.on_message(Acceptance)
async def handle_acceptance(ctx: Context, sender: str, msg: Acceptance):
ctx.logger.info(f'({msg.proposal_id}) accepted at price {msg.price}')


@alice.on_message(Reject)
async def handle_reject(ctx: Context, sender: str, msg: Reject):
ctx.logger.info(f'({msg.proposal_id}) rejected because {msg.reason}')


@alice.on_message(CounterProposal)
async def handle_counter_proposal(ctx: Context, sender: str, msg: CounterProposal):
ctx.logger.info(f'({msg.proposal_id}) counter offer for {msg.price}')

# evaluate the counter proposal
next_price = ((msg.price - ALICE_TARGET_MIN_PRICE) // 2) + ALICE_TARGET_MIN_PRICE

# attempt to negotiate down
await ctx.send(
bob_address,
Proposal(
id=uuid4(),
item=ALICE_TARGET_ITEM,
price=next_price,
)
)


@alice.on_interval(10)
async def on_interval(ctx: Context):
proposal_id = uuid4()
starting_price = ALICE_TARGET_MIN_PRICE

ctx.logger.info(f'({proposal_id}) proposing at price {starting_price}')

# send the proposal to Bob
await ctx.send(
bob_address,
Proposal(
id=proposal_id,
item=ALICE_TARGET_ITEM,
price=starting_price
)
)
31 changes: 31 additions & 0 deletions integrations/agent-negotiation/negotiation/bob.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from uagents import Agent, Context

from negotiation.messages import Proposal, CounterProposal, Acceptance, Reject

BOB_TARGET_MIN_PRICE = 100.0
BOB_TARGET_MAX_PRICE = 150.0
BOB_TARGET_ITEM = 'widget'

bob = Agent(name='bob', seed='bobs super secret seed phrase')
print('Bob address: ', bob.address)


@bob.on_message(Proposal)
async def handle_proposal(ctx: Context, sender: str, msg: Proposal):
ctx.logger.info(f'({msg.id}) proposal at price {msg.price}')

# if the proposal is not for the target item then it will be rejected
if msg.item != BOB_TARGET_ITEM:
await ctx.send(sender, Reject(proposal_id=msg.id, reason='I am not interested in that item'))
return

# sanity check
assert msg.item == BOB_TARGET_ITEM

# if the price is right then accept the proposal
if BOB_TARGET_MIN_PRICE <= msg.price:
await ctx.send(sender, Acceptance(proposal_id=msg.id, item=msg.item, price=msg.price))
return

# if the price is not right then counter with a proposal
await ctx.send(sender, CounterProposal(proposal_id=msg.id, item=msg.item, price=BOB_TARGET_MAX_PRICE))
25 changes: 25 additions & 0 deletions integrations/agent-negotiation/negotiation/messages.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from pydantic import UUID4
from uagents import Model


class Proposal(Model):
id: UUID4
item: str
price: float


class Reject(Model):
proposal_id: UUID4
reason: str


class CounterProposal(Model):
proposal_id: UUID4
item: str
price: float


class Acceptance(Model):
proposal_id: UUID4
item: str
price: float
Loading

0 comments on commit a02502a

Please sign in to comment.