mirror of
https://github.com/arkorty/B.Tech-Project-III.git
synced 2026-04-19 12:41:48 +00:00
120 lines
5.2 KiB
Python
120 lines
5.2 KiB
Python
from features.base_feature import BaseFeature
|
|
from tools.tavily_search import TavilySearchTool
|
|
|
|
_tavily = TavilySearchTool()
|
|
|
|
|
|
class MarketplaceFeature(BaseFeature):
|
|
|
|
async def get_context(self, preferences_a: dict, preferences_b: dict, user_a_id: int = None, user_b_id: int = None) -> str:
|
|
"""
|
|
Fetch real market prices via Tavily so agents negotiate around
|
|
actual reference prices, not guesses.
|
|
"""
|
|
raw_a = preferences_a.get("raw_details", {})
|
|
raw_b = preferences_b.get("raw_details", {})
|
|
|
|
item = (
|
|
raw_a.get("item") or raw_b.get("item")
|
|
or preferences_a.get("goal", "item")[:60]
|
|
)
|
|
seller_min = raw_a.get("minimum_price") or raw_a.get("min_price") or raw_a.get("asking_price") or ""
|
|
seller_asking = raw_a.get("asking_price") or raw_a.get("price") or ""
|
|
buyer_max = raw_b.get("maximum_budget") or raw_b.get("max_budget") or raw_b.get("budget") or ""
|
|
buyer_offer = raw_b.get("offer_price") or raw_b.get("price") or ""
|
|
|
|
# Flip if B is selling
|
|
role_a = raw_a.get("role", "")
|
|
role_b = raw_b.get("role", "")
|
|
if role_b == "seller":
|
|
seller_min = raw_b.get("minimum_price") or raw_b.get("min_price") or ""
|
|
seller_asking = raw_b.get("asking_price") or raw_b.get("price") or ""
|
|
buyer_max = raw_a.get("maximum_budget") or raw_a.get("max_budget") or raw_a.get("budget") or ""
|
|
buyer_offer = raw_a.get("offer_price") or raw_a.get("price") or ""
|
|
|
|
market_text = ""
|
|
try:
|
|
query = f"{item} used price India 2026"
|
|
result = await _tavily.execute(query)
|
|
answer = result.get("answer", "")
|
|
results = result.get("results", [])[:3]
|
|
parts = []
|
|
if answer:
|
|
parts.append(f"Market summary: {answer[:300]}")
|
|
for r in results:
|
|
title = r.get("title", "")
|
|
content = r.get("content", "")[:120]
|
|
if title:
|
|
parts.append(f" • {title}: {content}")
|
|
market_text = "\n".join(parts)
|
|
except Exception as e:
|
|
market_text = f"Market search unavailable ({e}). Use your knowledge of {item} pricing."
|
|
|
|
lines = [
|
|
"MARKETPLACE NEGOTIATION DOMAIN RULES:",
|
|
"• Seller must NOT go below their minimum price (hard constraint).",
|
|
"• Buyer must NOT exceed their maximum budget (hard constraint).",
|
|
"• Classic anchoring: seller starts at asking price, buyer starts with lower offer.",
|
|
"• Concede in diminishing increments (e.g., ₹3K, ₹2K, ₹1K).",
|
|
"• Delivery/pickup can be offered as a non-cash concession worth ₹500-1000.",
|
|
"• If gap > 20% after 3 rounds, propose splitting the difference or escalate.",
|
|
"• Cite the market price from the data below to justify your position.",
|
|
]
|
|
if item:
|
|
lines.append(f"\nItem being traded: {item}")
|
|
if seller_asking:
|
|
lines.append(f"Seller asking: ₹{seller_asking}")
|
|
if seller_min:
|
|
lines.append(f"Seller minimum (hard floor): ₹{seller_min}")
|
|
if buyer_max:
|
|
lines.append(f"Buyer maximum budget (hard ceiling): ₹{buyer_max}")
|
|
if buyer_offer:
|
|
lines.append(f"Buyer's opening offer: ₹{buyer_offer}")
|
|
if market_text:
|
|
lines.append(f"\nMARKET PRICE DATA (cite this):\n{market_text}")
|
|
|
|
return "\n".join(lines)
|
|
|
|
def format_resolution(
|
|
self, resolution: dict, preferences_a: dict, preferences_b: dict
|
|
) -> str:
|
|
status = resolution.get("status", "resolved")
|
|
final = resolution.get("final_proposal", {})
|
|
details = final.get("details", {})
|
|
rounds = resolution.get("rounds_taken", "?")
|
|
summary = resolution.get("summary", "")
|
|
|
|
raw_a = preferences_a.get("raw_details", {})
|
|
raw_b = preferences_b.get("raw_details", {})
|
|
item = raw_a.get("item") or raw_b.get("item") or "Item"
|
|
|
|
if status == "escalated":
|
|
return (
|
|
f"⚠️ *{item} Deal — Human Decision Needed*\n\n"
|
|
f"_{summary}_\n\n"
|
|
f"Agents couldn't bridge the price gap in {rounds} round(s). "
|
|
f"Please negotiate directly."
|
|
)
|
|
|
|
agreed_price = (
|
|
details.get("agreed_price") or details.get("price")
|
|
or details.get("final_price") or details.get("amount")
|
|
or final.get("summary", "")
|
|
)
|
|
delivery = details.get("delivery") or details.get("handover") or ""
|
|
market_ref = details.get("market_price") or details.get("market_reference") or ""
|
|
|
|
lines = [f"🛒 *Deal Closed!*\n"]
|
|
lines.append(f"📦 *Item:* {item}")
|
|
if agreed_price:
|
|
lines.append(f"💰 *Agreed price:* ₹{agreed_price}")
|
|
if delivery:
|
|
lines.append(f"🚚 *Delivery/Handover:* {delivery}")
|
|
if market_ref:
|
|
lines.append(f"📊 *Market reference:* ₹{market_ref}")
|
|
lines.append(f"\n⏱ Deal closed in {rounds} round(s)")
|
|
if summary and summary != "Agreement reached":
|
|
lines.append(f"_{summary}_")
|
|
|
|
return "\n".join(lines)
|