Spaces:
Runtime error
Runtime error
import logging | |
import queue | |
import threading | |
import time | |
import gradio as gr | |
from deal_agent_framework import DealAgentFramework | |
from agents.deals import Opportunity, Deal | |
from log_utils import reformat | |
import plotly.graph_objects as go | |
class QueueHandler(logging.Handler): | |
def __init__(self, log_queue): | |
super().__init__() | |
self.log_queue = log_queue | |
def emit(self, record): | |
self.log_queue.put(self.format(record)) | |
def html_for(log_data): | |
output = '<br>'.join(log_data[-18:]) | |
return f""" | |
<div id="scrollContent" style="height: 400px; overflow-y: auto; border: 1px solid #ccc; background-color: #222229; padding: 10px;"> | |
{output} | |
</div> | |
""" | |
def setup_logging(log_queue): | |
handler = QueueHandler(log_queue) | |
formatter = logging.Formatter( | |
"[%(asctime)s] %(message)s", | |
datefmt="%Y-%m-%d %H:%M:%S %z", | |
) | |
handler.setFormatter(formatter) | |
logger = logging.getLogger() | |
logger.addHandler(handler) | |
logger.setLevel(logging.INFO) | |
class App: | |
def __init__(self): | |
self.agent_framework = None | |
def get_agent_framework(self): | |
if not self.agent_framework: | |
self.agent_framework = DealAgentFramework() | |
self.agent_framework.init_agents_as_needed() | |
return self.agent_framework | |
def run(self): | |
with gr.Blocks(title="The Price is Right", fill_width=True) as ui: | |
log_data = gr.State([]) | |
def table_for(opps): | |
return [[opp.deal.product_description, f"${opp.deal.price:.2f}", f"${opp.estimate:.2f}", f"${opp.discount:.2f}", opp.deal.url] for opp in opps] | |
def update_output(log_data, log_queue, result_queue): | |
initial_result = table_for(self.get_agent_framework().memory) | |
final_result = None | |
while True: | |
try: | |
message = log_queue.get_nowait() | |
log_data.append(reformat(message)) | |
yield log_data, html_for(log_data), final_result or initial_result | |
except queue.Empty: | |
try: | |
final_result = result_queue.get_nowait() | |
yield log_data, html_for(log_data), final_result or initial_result | |
except queue.Empty: | |
if final_result is not None: | |
break | |
time.sleep(0.1) | |
def get_initial_plot(): | |
fig = go.Figure() | |
fig.update_layout( | |
title='Loading vector DB...', | |
height=400, | |
) | |
return fig | |
def get_plot(): | |
documents, vectors, colors = DealAgentFramework.get_plot_data(max_datapoints=1000) | |
# Create the 3D scatter plot | |
fig = go.Figure(data=[go.Scatter3d( | |
x=vectors[:, 0], | |
y=vectors[:, 1], | |
z=vectors[:, 2], | |
mode='markers', | |
marker=dict(size=2, color=colors, opacity=0.7), | |
)]) | |
fig.update_layout( | |
scene=dict(xaxis_title='x', | |
yaxis_title='y', | |
zaxis_title='z', | |
aspectmode='manual', | |
aspectratio=dict(x=2.2, y=2.2, z=1), # Make x-axis twice as long | |
camera=dict( | |
eye=dict(x=1.6, y=1.6, z=0.8) # Adjust camera position | |
)), | |
height=400, | |
margin=dict(r=5, b=1, l=5, t=2) | |
) | |
return fig | |
def do_run(): | |
new_opportunities = self.get_agent_framework().run() | |
table = table_for(new_opportunities) | |
return table | |
def run_with_logging(initial_log_data): | |
log_queue = queue.Queue() | |
result_queue = queue.Queue() | |
setup_logging(log_queue) | |
def worker(): | |
result = do_run() | |
result_queue.put(result) | |
thread = threading.Thread(target=worker) | |
thread.start() | |
for log_data, output, final_result in update_output(initial_log_data, log_queue, result_queue): | |
yield log_data, output, final_result | |
def do_select(selected_index: gr.SelectData): | |
opportunities = self.get_agent_framework().memory | |
row = selected_index.index[0] | |
opportunity = opportunities[row] | |
self.get_agent_framework().planner.messenger.alert(opportunity) | |
with gr.Row(): | |
gr.Markdown('<div style="text-align: center;font-size:24px"><strong>The Price is Right</strong> - Autonomous Agent Framework that hunts for deals</div>') | |
with gr.Row(): | |
gr.Markdown('<div style="text-align: center;font-size:14px">A proprietary fine-tuned LLM deployed on Modal and a RAG pipeline with a frontier model collaborate to send push notifications with great online deals.</div>') | |
with gr.Row(): | |
opportunities_dataframe = gr.Dataframe( | |
headers=["Deals found so far", "Price", "Estimate", "Discount", "URL"], | |
wrap=True, | |
column_widths=[6, 1, 1, 1, 3], | |
row_count=10, | |
col_count=5, | |
max_height=400, | |
) | |
with gr.Row(): | |
with gr.Column(scale=1): | |
logs = gr.HTML() | |
with gr.Column(scale=1): | |
plot = gr.Plot(value=get_plot(), show_label=False) | |
ui.load(run_with_logging, inputs=[log_data], outputs=[log_data, logs, opportunities_dataframe]) | |
timer = gr.Timer(value=300, active=True) | |
timer.tick(run_with_logging, inputs=[log_data], outputs=[log_data, logs, opportunities_dataframe]) | |
opportunities_dataframe.select(do_select) | |
ui.launch(share=False, inbrowser=True) | |
if __name__=="__main__": | |
App().run() | |