Capstone / agents /autonomous_planning_agent.py
prabalGaur's picture
Upload folder using huggingface_hub
58bd26a verified
Raw
History Blame Contribute Delete
7.43 kB
from typing import Optional, List, Dict
from agents.agent import Agent
from agents.deals import Deal, Opportunity
from agents.scanner_agent import ScannerAgent
from agents.ensemble_agent import EnsembleAgent
from agents.messaging_agent import MessagingAgent
from openai import OpenAI
import json
class AutonomousPlanningAgent(Agent):
name = "Autonomous Planning Agent"
color = Agent.GREEN
MODEL = "gpt-5.1"
def __init__(self, collection):
"""
Create instances of the 3 Agents that this planner coordinates across
"""
self.log("Autonomous Planning Agent is initializing")
self.scanner = ScannerAgent()
self.ensemble = EnsembleAgent(collection)
self.messenger = MessagingAgent()
self.openai = OpenAI()
self.memory = None
self.opportunity = None
self.log("Autonomous Planning Agent is ready")
def scan_the_internet_for_bargains(self) -> str:
"""
Run the tool to scan
"""
self.log("Autonomous Planning agent is calling scanner")
results = self.scanner.scan(memory=self.memory)
return results.model_dump_json() if results else "No deals found"
def estimate_true_value(self, description: str) -> str:
"""
Run the tool to estimate true value
"""
self.log("Autonomous Planning agent is estimating value via Ensemble Agent")
estimate = self.ensemble.price(description)
return f"The estimated true value of {description} is {estimate}"
def notify_user_of_deal(
self, description: str, deal_price: float, estimated_true_value: float, url: str
) -> Dict:
"""
Run the tool to notify the user
"""
if self.opportunity:
self.log("Autonomous Planning agent is trying to notify the user a 2nd time; ignoring")
else:
self.log("Autonomous Planning agent is notifying user")
self.messenger.notify(description, deal_price, estimated_true_value, url)
deal = Deal(product_description=description, price=deal_price, url=url)
discount = estimated_true_value - deal_price
self.opportunity = Opportunity(
deal=deal, estimate=estimated_true_value, discount=discount
)
return "Notification sent ok"
scan_function = {
"name": "scan_the_internet_for_bargains",
"description": "Returns top bargains scraped from the internet along with the price each item is being offered for",
"parameters": {
"type": "object",
"properties": {},
"required": [],
"additionalProperties": False,
},
}
estimate_function = {
"name": "estimate_true_value",
"description": "Given the description of an item, estimate how much it is actually worth",
"parameters": {
"type": "object",
"properties": {
"description": {
"type": "string",
"description": "The description of the item to be estimated",
},
},
"required": ["description"],
"additionalProperties": False,
},
}
notify_function = {
"name": "notify_user_of_deal",
"description": "Send the user a push notification about the single most compelling deal; only call this one time",
"parameters": {
"type": "object",
"properties": {
"description": {
"type": "string",
"description": "The description of the item itself scraped from the internet",
},
"deal_price": {
"type": "number",
"description": "The price offered by this deal scraped from the internet",
},
"estimated_true_value": {
"type": "number",
"description": "The estimated actual value that this is worth",
},
"url": {
"type": "string",
"description": "The URL of this deal as scraped from the internet",
},
},
"required": ["description", "deal_price", "estimated_true_value", "url"],
"additionalProperties": False,
},
}
def get_tools(self):
"""
Return the json for the tools to be used
"""
return [
{"type": "function", "function": self.scan_function},
{"type": "function", "function": self.estimate_function},
{"type": "function", "function": self.notify_function},
]
def handle_tool_call(self, message):
"""
Actually call the tools associated with this message
"""
mapping = {
"scan_the_internet_for_bargains": self.scan_the_internet_for_bargains,
"estimate_true_value": self.estimate_true_value,
"notify_user_of_deal": self.notify_user_of_deal,
}
results = []
for tool_call in message.tool_calls:
tool_name = tool_call.function.name
arguments = json.loads(tool_call.function.arguments)
tool = mapping.get(tool_name)
result = tool(**arguments) if tool else ""
results.append({"role": "tool", "content": result, "tool_call_id": tool_call.id})
return results
system_message = "You find great deals on bargain products using your tools, and notify the user of the best bargain."
user_message = """
First, use your tool to scan the internet for bargain deals. Then for each deal, use your tool to estimate its true value.
Then pick the single most compelling deal where the price is much lower than the estimated true value, and use your tool to notify the user.
Then just reply OK to indicate success.
"""
messages = [
{"role": "system", "content": system_message},
{"role": "user", "content": user_message},
]
def plan(self, memory: List[str] = []) -> Optional[Opportunity]:
"""
Run the full workflow, providing the LLM with tools to surface scraped deals to the user
:param memory: a list of URLs that have been surfaced in the past
:return: an Opportunity if one was surfaced, otherwise None
"""
self.log("Autonomous Planning Agent is kicking off a run")
self.memory = memory
self.opportunity = None
messages = self.messages[:]
done = False
while not done:
response = self.openai.chat.completions.create(
model=self.MODEL, messages=messages, tools=self.get_tools()
)
if response.choices[0].finish_reason == "tool_calls":
message = response.choices[0].message
results = self.handle_tool_call(message)
messages.append(message)
messages.extend(results)
else:
done = True
reply = response.choices[0].message.content
self.log(f"Autonomous Planning Agent completed with: {reply}")
return self.opportunity