App_Simulator / app.py
jjz5463's picture
record result update
c222873
raw
history blame
8 kB
import gradio as gr
from chatbot_simulator import ChatbotSimulation
from huggingface_hub import HfApi, create_repo
from datasets import load_dataset
import json_repair
import random
import os
import re
os.environ["TOKENIZERS_PARALLELISM"] = "false"
openai_api_key = os.getenv("OPENAI_API_KEY")
task_completed = 0
task_completed_steps = None
def is_task_incomplete(example):
return example["task_completed"] is None and example["task_completed_steps"] is None
def is_task_given_up(example):
return example["task_completed"] == 0 and example["task_completed_steps"] == 0
def is_task_incomplete_idx(example, idx):
return example["task_completed"] is None and example["task_completed_steps"] is None
def is_task_given_up_idx(example, idx):
return example["task_completed"] == 0 and example["task_completed_steps"] == 0
class AppSimulator:
def __init__(self, openai_api_key):
self.simulation = None
self.openai_api_key = openai_api_key
self.app_name = None
def initialize_simulator(self, sitemap_url, progress=gr.Progress(track_tqdm=True)):
"""Initialize the simulator with retries and elapsed time tracking."""
synthetic_sitemap = load_dataset(sitemap_url, "sitemap", split='train')
app_name, sitemap, page_details, user_state, system_data = None, None, None, None, None
for row in synthetic_sitemap:
if row['name'] == 'app_name':
app_name = row['value'] # Use `eval` to convert the string to a list
elif row['name'] == 'sitemap':
sitemap = json_repair.loads(row['value'])
elif row['name'] == 'page_details':
page_details = json_repair.loads(row['value'])
elif row['name'] == 'user_state':
user_state = json_repair.loads(row['value'])
elif row['name'] == 'system_data':
system_data = json_repair.loads(row['value'])
self.app_name = app_name
human_result_url = "jjz5463/simulator_human_result"
synthetic_tasks = load_dataset(human_result_url, app_name, split='train')
incomplete_tasks = synthetic_tasks.filter(is_task_incomplete)
give_up_tasks = synthetic_tasks.filter(is_task_given_up)
if len(incomplete_tasks) > 0:
incomplete_task = incomplete_tasks[0]
task = incomplete_task["tasks"]
solution = incomplete_task["steps"]
user_data = incomplete_task["attributes"]["user_data"]
elif len(give_up_tasks) > 0:
give_up_task = give_up_tasks[0]
task = give_up_task["tasks"]
solution = give_up_task["steps"]
user_data = give_up_task["attributes"]["user_data"]
else:
return "All tasks in this app have been completed!"
self.simulation = ChatbotSimulation(
app_name=app_name,
site_map=sitemap,
page_details=page_details,
user_state=user_state,
system_data=system_data,
user_data=user_data,
task=task,
solution=solution,
log_location=f'conversation_log_{app_name}.txt',
openai_api_key=openai_api_key,
agent='llm'
)
initial_message = self.simulation.start_conversation()
progress.update("Initialization Successful")
return initial_message # Return the initial assistant message for chat
def chat_interaction(self, user_input, history):
"""Handle one round of conversation."""
return self.simulation.one_conversation_round(user_input)
# Initialize the simulator
simulator_app = AppSimulator(openai_api_key=openai_api_key)
def chat(user_input, history):
"""Chat handler that validates input and interacts with the simulator."""
response = simulator_app.chat_interaction(user_input, history)
# Initialize variables for task completion and steps
# Define the pattern for matching the response
pattern = r"Task completed! You took (\d+) steps\."
match = re.match(pattern, response)
global task_completed
global task_completed_steps
task_completed = 0
task_completed_steps = None
if match:
task_completed = 1
task_completed_steps = int(match.group(1))
human_result_url = "jjz5463/simulator_human_result"
app_name = simulator_app.app_name
synthetic_tasks = load_dataset(human_result_url, app_name, split='train')
incomplete_tasks = synthetic_tasks.filter(is_task_incomplete_idx, with_indices=True,)
if len(incomplete_tasks) > 0:
incomplete_task_index = incomplete_tasks['"__index"'][0]
synthetic_tasks = synthetic_tasks.map(
lambda example, idx: {
"task_completed": task_completed if idx == incomplete_task_index else example["task_completed"],
"task_completed_steps": task_completed_steps if idx == incomplete_task_index else example["task_completed_steps"],
},
with_indices=True,
)
# Push the updated dataset back to Hugging Face
synthetic_tasks.push_to_hub(human_result_url)
return response
def give_up():
"""Handle the Give-Up action by marking the first incomplete task as abandoned."""
global task_completed, task_completed_steps
task_completed = 0
task_completed_steps = 0
# Access the app_name from the simulator instance
app_name = simulator_app.app_name
if not app_name:
return "Simulator has not been initialized with an app!"
# Load the human result dataset
human_result_url = "jjz5463/simulator_human_result"
synthetic_tasks = load_dataset(human_result_url, app_name, split='train')
# Find the first incomplete task
incomplete_tasks = synthetic_tasks.filter(is_task_incomplete_idx, with_indices=True,)
if len(incomplete_tasks) > 0:
incomplete_task_index = incomplete_tasks['"__index"'][0]
# Update the dataset to mark the task as abandoned
synthetic_tasks = synthetic_tasks.map(
lambda example, idx: {
"task_completed": task_completed if idx == incomplete_task_index else example["task_completed"],
"steps": task_completed_steps if idx == incomplete_task_index else example["steps"],
},
with_indices=True,
)
# Push the updated dataset back to Hugging Face
synthetic_tasks.push_to_hub(human_result_url)
return "Task marked as abandoned (Give-Up action)."
else:
return "No incomplete tasks found to abandon!"
# Gradio Interface using ChatInterface
with gr.Blocks(fill_height=True) as demo:
gr.Markdown("## Simulator Setup")
# Input fields for initialization
sitemap_input = gr.Textbox(label="Sitemap", placeholder="Enter the Hugging Face link to sitemap... (eg.jjz5463/DoorDash_synthetic_sitemap)")
initialize_button = gr.Button("Initialize Simulator")
# Status block to display initialization progress with elapsed time
status = gr.Textbox(label="Status", interactive=False)
# Chat interface to handle user interactions
chat_interface = gr.ChatInterface(fn=chat, type='messages')
give_up_button = gr.Button("Give Up")
# Define the callback function to initialize the simulator and update status
def initialize_and_start_chat(sitemap):
return simulator_app.initialize_simulator(sitemap) # Use progress tracking
# Set up the button click to initialize simulator and update status only
initialize_button.click(
fn=initialize_and_start_chat,
inputs=[sitemap_input],
outputs=status # Update only the status block
)
# Set up the Give-Up button click to update the dataset
give_up_button.click(
fn=give_up,
inputs=[],
outputs=status # Update the status with the give-up message
)
# Launch the app
demo.launch()