diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..82f9275 --- /dev/null +++ b/.gitignore @@ -0,0 +1,162 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/latest/usage/project/#working-with-version-control +.pdm.toml +.pdm-python +.pdm-build/ + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..2bc86ff --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Panasonic Connect + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..473a0d7 --- /dev/null +++ b/README.md @@ -0,0 +1,27 @@ +# RAP: Retrieval-Augmented Planning with Contextual Memory for Multimodal LLM Agents +This repository is the implementation of [RAP](https://arxiv.org/abs/2402.03610). + +![RAP figure](./figure/figure.png) + +# Get Started +Please refer to the following README's for each benchmark. +* [ALFWorld](./alfworld/README.md) +* [WebShop](./webshop/README.md) +* Franka Kitchen +* MetaWorld + +# Citation +If you find RAP helpful in your research, please consider citing. +```bibtex +@misc{kagaya2024rap, + title={RAP: Retrieval-Augmented Planning with Contextual Memory for Multimodal LLM Agents}, + author={Tomoyuki Kagaya and Thong Jing Yuan and Yuxuan Lou and Jayashree Karlekar and Sugiri Pranata and Akira Kinose and Koki Oguri and Felix Wick and Yang You}, + year={2024}, + eprint={2402.03610}, + archivePrefix={arXiv}, + primaryClass={cs.LG} +} +``` + +# License +MIT license diff --git a/alfworld/README.md b/alfworld/README.md new file mode 100644 index 0000000..d7023d8 --- /dev/null +++ b/alfworld/README.md @@ -0,0 +1,25 @@ +# Get Started +1. Move alfworld directory and install requirements +```bash +cd ./alfworld +pip install -r requirements.txt +``` + +2. According to the [instruction](https://github.com/alfworld/alfworld?tab=readme-ov-file#quickstart), download the data and set environment variables + +3. Prepare OpenAI API key and put the key in ```OpenAI_api_key.txt``` + +4. Run RAP on ALFWorld +```bash +python main.py +``` + +Following are the hyper-parametes for RAP. + +* num_trials: Number of recursive trials. Default is 3. +* num_steps: Maximum steps in one task. Default is 50. +* model: Model to be used in evaluation. Default is "gpt-3.5-turbo-instruct". +* output: Folder path to output logs and memory. +* emb_model: Embedding model to be used in evaluation. Default is "sentence-transformers/all-MiniLM-L6-v2". + +Also, Python 3.11 is recommended for evaluation. \ No newline at end of file diff --git a/alfworld/configs/base_config.yaml b/alfworld/configs/base_config.yaml new file mode 100644 index 0000000..653d470 --- /dev/null +++ b/alfworld/configs/base_config.yaml @@ -0,0 +1,145 @@ +dataset: + data_path: '$ALFWORLD_DATA/json_2.1.1/train' + eval_id_data_path: '$ALFWORLD_DATA/json_2.1.1/valid_seen' # null/None to disable + eval_ood_data_path: '$ALFWORLD_DATA/json_2.1.1/valid_unseen' # null/None to disable + num_train_games: -1 # max training games (<=0 indicates full dataset) + num_eval_games: -1 # max evaluation games (<=0 indicates full dataset) + +logic: + domain: '$ALFWORLD_DATA/logic/alfred.pddl' # PDDL domain file that defines the world dynamics + grammar: '$ALFWORLD_DATA/logic/alfred.twl2' # Grammar file that defines the text feedbacks + +env: + type: 'AlfredTWEnv' # 'AlfredTWEnv' or 'AlfredThorEnv' or 'AlfredHybrid' + regen_game_files: False # check if game is solvable by expert and save to game.tw-pddl file + domain_randomization: False # shuffle Textworld print order and object id nums + task_types: [1, 2, 3, 4, 5, 6] # task-type ids: 1 - Pick & Place, 2 - Examine in Light, 3 - Clean & Place, 4 - Heat & Place, 5 - Cool & Place, 6 - Pick Two & Place + expert_timeout_steps: 150 # max steps before timeout for expert to solve the task + expert_type: "handcoded" # 'handcoded' or 'downward'. Note: the downward planner is very slow for real-time use + goal_desc_human_anns_prob: 0.0 # prob of using human-annotated goal language instead of templated goals (1.0 indicates all human annotations from ALFRED) + + hybrid: + start_eps: 100000 # starting episode of hybrid training, tw-only training upto this point + thor_prob: 0.5 # prob of AlfredThorEnv during hybrid training + eval_mode: "tw" # 'tw' or 'thor' - env used for evaluation during hybrid training + + thor: + screen_width: 300 # width of THOR window + screen_height: 300 # height of THOR window + smooth_nav: False # smooth rotations, looks, and translations during navigation (very slow) + save_frames_to_disk: False # save frame PNGs to disk (useful for making videos) + save_frames_path: './videos/' # path to save frame PNGs + +controller: + type: 'oracle' # 'oracle' or 'oracle_astar' or 'mrcnn' or 'mrcnn_astar' (aka BUTLER) + debug: False + load_receps: True # load receptacle locations from precomputed dict (if available) + +mask_rcnn: + pretrained_model_path: '$ALFWORLD_DATA/detectors/mrcnn.pth' + +general: + random_seed: 42 + use_cuda: True # disable this when running on machine without cuda + visdom: False # plot training/eval curves, run with visdom server + task: 'alfred' + training_method: 'dagger' # 'dqn' or 'dagger' + save_path: './training/' # path to save pytorch models + observation_pool_capacity: 3 # k-size queue, 0 indicates no observation + hide_init_receptacles: False # remove initial observation containing navigable receptacles + + training: + batch_size: 10 + max_episode: 50000 + smoothing_eps: 0.1 + optimizer: + learning_rate: 0.001 + clip_grad_norm: 5 + + evaluate: + run_eval: True + batch_size: 10 + env: + type: "AlfredTWEnv" + + checkpoint: + report_frequency: 1000 # report every N episode + experiment_tag: 'test' # name of experiment + load_pretrained: False # during test, enable this so that the agent load your pretrained model + load_from_tag: 'not loading anything' # name of pre-trained model to load in save_path + + model: + encoder_layers: 1 + decoder_layers: 1 + encoder_conv_num: 5 + block_hidden_dim: 64 + n_heads: 1 + dropout: 0.1 + block_dropout: 0.1 + recurrent: True + +rl: + action_space: "admissible" # 'admissible' (candidates from text engine) or 'generation' (seq2seq-style generation) or 'beam_search_choice' or 'exhaustive' (not working) + max_target_length: 20 # max token length for seq2seq generation + beam_width: 10 # 1 means greedy + generate_top_k: 3 + + training: + max_nb_steps_per_episode: 50 # terminate after this many steps + learn_start_from_this_episode: 0 # delay updates until this epsiode + target_net_update_frequency: 500 # sync target net with online net per this many epochs + + replay: + accumulate_reward_from_final: True + count_reward_lambda: 0.0 # 0 to disable + novel_object_reward_lambda: 0.0 # 0 to disable + discount_gamma_game_reward: 0.9 + discount_gamma_count_reward: 0.5 + discount_gamma_novel_object_reward: 0.5 + replay_memory_capacity: 500000 # adjust this depending on your RAM size + replay_memory_priority_fraction: 0.5 + update_per_k_game_steps: 5 + replay_batch_size: 64 + multi_step: 3 + replay_sample_history_length: 4 + replay_sample_update_from: 2 + + epsilon_greedy: + noisy_net: False # if this is true, then epsilon greedy is disabled + epsilon_anneal_episodes: 1000 # -1 if not annealing + epsilon_anneal_from: 0.3 + epsilon_anneal_to: 0.1 + +dagger: + action_space: "generation" # 'admissible' (candidates from text engine) or 'generation' (seq2seq-style generation) or 'exhaustive' (not working) + max_target_length: 20 # max token length for seq2seq generation + beam_width: 10 # 1 means greedy + generate_top_k: 5 + unstick_by_beam_search: False # use beam-search for failed actions, set True during evaluation + + training: + max_nb_steps_per_episode: 50 # terminate after this many steps + + fraction_assist: + fraction_assist_anneal_episodes: 50000 + fraction_assist_anneal_from: 1.0 + fraction_assist_anneal_to: 0.01 + + fraction_random: + fraction_random_anneal_episodes: 0 + fraction_random_anneal_from: 0.0 + fraction_random_anneal_to: 0.0 + + replay: + replay_memory_capacity: 500000 + update_per_k_game_steps: 5 + replay_batch_size: 64 + replay_sample_history_length: 4 + replay_sample_update_from: 2 + +vision_dagger: + model_type: "resnet" # 'resnet' (whole image features) or 'maskrcnn_whole' (whole image MaskRCNN feats) or 'maskrcnn' (top k MaskRCNN detection feats) or 'no_vision' (zero vision input) + resnet_fc_dim: 64 + maskrcnn_top_k_boxes: 10 # top k box features + use_exploration_frame_feats: False # append feats from initial exploration (memory intensive!) + sequence_aggregation_method: "average" # 'sum' or 'average' or 'rnn' diff --git a/alfworld/main.py b/alfworld/main.py new file mode 100644 index 0000000..16b8b5e --- /dev/null +++ b/alfworld/main.py @@ -0,0 +1,334 @@ +import os,sys +import yaml +import json +import numpy as np +import transformers +import torch +import argparse + +parser = argparse.ArgumentParser() +parser.add_argument("--num_trials", type=int, default=3, help="The number of trials") +parser.add_argument("--num_steps", type=int, default=50, help="The number of steps") +parser.add_argument("--model", type=str, default="gpt-3.5-turbo-instruct", choices=["gpt-3.5-turbo-instruct", "gpt-4-0613", "meta-llama/Llama-2-13b-chat-hf"], help="The model name") +parser.add_argument("--output", type=str, default="output", help="The output folder") +parser.add_argument("--emb_model", type=str, default="sentence-transformers/all-MiniLM-L6-v2", choices=["sentence-transformers/all-MiniLM-L6-v2", "sentence-transformers/all-MiniLM-L12-v2"], help="The model name") +args = parser.parse_args() + +os.makedirs(args.output, exist_ok=True) + +with open('./configs/base_config.yaml') as reader: + config = yaml.safe_load(reader) + +ret_key_examples = open('prompts/retrieval_prompt.txt').readlines() +ret_key_examples = ''.join(ret_key_examples) + +if 'Llama-2' in args.model: + # llama2 + from transformers import AutoModelForCausalLM + from transformers import AutoTokenizer + + model_name = args.model + model = AutoModelForCausalLM.from_pretrained( + model_name, load_in_4bit=True, device_map="auto" + ) + tokenizer = AutoTokenizer.from_pretrained(model_name) + + pipeline = transformers.pipeline( + "text-generation", + model=model, + tokenizer=tokenizer, + ) +elif 'gpt' in args.model: + #openai + import openai + from openai import OpenAI + os.environ["OPENAI_API_KEY"] = open('OpenAI_api_key.txt').readline() + openai.api_key = os.environ["OPENAI_API_KEY"] + client = OpenAI() + +def llm(prompt, stop=["\n"]): + + if 'Llama-2' in args.model: + sequences = pipeline( + prompt, + do_sample=True, + top_k=10, + num_return_sequences=1, + eos_token_id=tokenizer.eos_token_id, + max_new_tokens=200, + return_full_text=False, + ) + text = sequences[0]['generated_text'] + elif 'gpt-3.5-turbo-instruct' == args.model: + response = client.completions.create( + model='gpt-3.5-turbo-instruct', + prompt=prompt[max(0,len(prompt)-4000*4):], # rough limitation for max_tokens + temperature=0.0, + max_tokens=100, + top_p=1, + frequency_penalty=0.0, + presence_penalty=0.0, + stop=stop + ) + text = response.choices[0].text + elif 'gpt-4-0613' == args.model: + completion = client.chat.completions.create( + model="gpt-4-0613", + messages=[ + {"role": "system", "content": "You are a helpful assistant for household task."}, + {"role": "user", "content": prompt}, + ], + temperature=0.5, + max_tokens=100, + top_p=1, + frequency_penalty=0.0, + presence_penalty=0.0, + stop=stop + ) + text = completion.choices[0].message.content + + if stop: + text = text.split('\n')[0] + if len(text) > 0 and text[0]=='>': + text = text[1:] + if len(text) > 0 and text[-1]=='.': + text = text[:-1] + return text.strip() + +# text embedding model +from sentence_transformers import SentenceTransformer +from sentence_transformers.util import cos_sim +model_embedding = SentenceTransformer(args.emb_model) + +import alfworld +import alfworld.agents.environment + +def process_ob(ob): + if ob.startswith('You arrive at loc '): + ob = ob[ob.find('. ')+2:] + return ob + +prefixes = { + 'pick_and_place': 'put', + 'pick_clean_then_place': 'clean', + 'pick_heat_then_place': 'heat', + 'pick_cool_then_place': 'cool', + 'look_at_obj': 'examine', + 'pick_two_obj': 'puttwo' +} +with open('./prompts/alfworld_3prompts.json', 'r') as f: + d_react = json.load(f) + +def generate_embeddings(memory): + print('num_retrieval',len(memory)) + embeddings = {} + for key in ['Task', 'Category', 'Plan', 'Actions']: + if key=='Actions': + retrieve_info = [m[key].copy() for m in memory] + for i in range(len(retrieve_info)): + for j in range(len(retrieve_info[i])): + retrieve_info[i][j] = retrieve_info[i][j].strip() + embeddings[key] = [model_embedding.encode(r) for r in retrieve_info] + continue + retrieve_info = [m[key] for m in memory] + # extract embeddings + embeddings[key] = model_embedding.encode(retrieve_info) + return embeddings + +def generate_examples(query, memory, embeddings, k=3, for_plan=False, act_len=0, mode='act', key=''): + # similarity on task, category, and plan + cos_scores_sum = [] + for key_tmp in ['Task', 'Category', 'Plan']: + if query[key_tmp]=='': continue + with torch.no_grad(): + query_embeddings = model_embedding.encode([query[key_tmp]]) + cos_scores = cos_sim(query_embeddings, embeddings[key_tmp])[0] + cos_scores_sum.append(cos_scores.tolist()) + cos_scores_sum = torch.sum(torch.tensor(cos_scores_sum), 0) + # retrieve examples for overall plan + if for_plan: + _, hits = torch.topk(cos_scores_sum, k=k) + ret_examples = [ 'Your task is to: ' + memory[h]['Task'] + '\n> ' + memory[h]['Plan'] + '\n' for h in hits] + return ret_examples + # similarity on action or observation + ret_scores=[] + ret_index=[] + with torch.no_grad(): + query_embeddings = model_embedding.encode([key]) + for emb in embeddings['Actions']: + if key=='': + ret_scores.append(0) + ret_index.append(0) + continue + elif mode=='act': + # pick up action embeddings + log_embeddings = emb[::2] + elif mode=='obs': + # pick up observation embeddings + log_embeddings = emb[1::2] + cos_scores = cos_sim(query_embeddings, log_embeddings).numpy() + ret_scores.append(np.max(cos_scores)) + ret_index.append(np.argmax(cos_scores)*2) + ret_scores = torch.FloatTensor(ret_scores) + # retrieve examples for action or action plan + _, hits = torch.topk(ret_scores+cos_scores_sum, k=k) + ret_examples = [] + for h in hits: + part = (max(0,ret_index[h]-act_len),min(len(memory[h]['Actions']),ret_index[h]+act_len)) + ret_examples.append('Task: ' + memory[h]['Task'] + '\nPlan: ' + memory[h]['Plan'] + '\n' + '\n'.join(memory[h]['Actions'][part[0]:part[1]]) + '\n') + return ret_examples + +def alfworld_run_react(prompt, ob, category, to_print=True): + target_task = ob.split('\n')[1].split(': ')[1] + init_prompt = prompt + ob + '\n>' + prompt = '' + actions = [] + if to_print: + print(ob) + sys.stdout.flush() + for i in range(1, args.num_steps): + action = llm(init_prompt + prompt) + observation, reward, done, info = env.step([action]) + observation, reward, done = process_ob(observation[0]), info['won'][0], done[0] + if action.startswith('think:'): + observation = 'OK.' + if to_print: + print(f'Act {i}: {action}\nObs {i}: {observation}') + sys.stdout.flush() + prompt += f' {action}\n{observation}\n>' + actions.append('> '+action) + actions.append(observation) + if done: + # extract overall plan + plan = actions[0].split('think: ')[1].strip() + actions = actions[2:] + # remove invalid actions and observations + inv_act_idx = np.where(np.array(actions)=='Nothing happens.')[0] + inv_act_idx = np.append( inv_act_idx, inv_act_idx-1) + actions = [actions[i] for i in range(len(actions)) if i not in inv_act_idx] + # remove locations in reasoning + actions = [ a.split('.')[0] if 'likely to appear' in a else a for a in actions] + data = { + 'Task': target_task, + 'Category': category, + 'Plan': plan, + 'Actions': actions, + } + return reward, data + return 0, '' + +def alfworld_run_rap(prompt, ob, category, memory, embeddings, to_print=True): + # init + if to_print: + print(ob) + sys.stdout.flush() + ob_prompt = 'Here is the task information.\n' + ob.split('\n')[0] + '\n' + target_task = ob.split('\n')[1].split(': ')[1] + + # planning + examples = generate_examples({'Task': target_task, 'Category': category, 'Plan': ''}, memory, embeddings, k=3, for_plan=True) + examples = 'Here are examples.\n' + ''.join(examples) + target_prompt = '\n' + 'Here is the task. Please make a plan from the examples.\n' + 'Your task is to: ' + target_task + '\n' + '> think: To solve the task,' + full_prompt = examples + target_prompt + plan = llm(full_prompt) + plan = 'To solve the task, '+plan.split('.')[0]+'.' + print('Plan: ' + plan) + + target_prompt = 'Here is the task. Please make an action from the examples.\nTask : ' + target_task + '\nPlan : ' + plan + '\n' + # data + data = { + 'Task': target_task, + 'Category': category, + 'Plan': plan, + 'Actions': '', + } + actions = [] + # extract examples + search_object = '' + reasoning = '' + ret_examples = generate_examples(data, memory, embeddings, k=4, act_len=20) + for i in range(1, args.num_steps): + # generate action with retrieval + examples = 'Here are examples.\n' + ''.join(ret_examples) + full_prompt = ob_prompt + examples + target_prompt + '\n'.join(data['Actions']) + '\n>' + action = llm(full_prompt) + + # input action into alfworld + observation, reward, done, info = env.step([action]) + observation, reward, done = process_ob(observation[0]), info['won'][0], done[0] + if action.startswith('think:'): + observation = 'OK.' + + if to_print: + print(f'Act {i}: {action}\nObs {i}: {observation}') + sys.stdout.flush() + # generate retrieval key + if 'think:' in action: + full_prompt = 'Here are examples.\n' + ret_key_examples + '\nHere is the task. Please make a plan from the examples.\n' + action + '\n>' + retrieve_key = llm(full_prompt) + print('Retrieval key',retrieve_key) + if 'search:' in retrieve_key: + search_object = retrieve_key.split('search:')[1].strip() + ret_examples = generate_examples(data, memory, embeddings, k=8, act_len=10, mode='obs', key = search_object) + elif 'action:' in retrieve_key: + reasoning = retrieve_key.split('action:')[1].strip() + ret_examples = generate_examples(data, memory, embeddings, k=4, act_len=20, mode='act', key = reasoning) + + # add action and observation + actions.append('> '+action) + actions.append(observation) + data['Actions'] = actions[-10:] + # finish + if done: + # remove invalid actions and observations + inv_act_idx = np.where(np.array(actions)=='Nothing happens.')[0] + inv_act_idx = np.append( inv_act_idx, inv_act_idx-1) + actions = [actions[i] for i in range(len(actions)) if i not in inv_act_idx] + # update actions for memory + data['Actions'] = actions + return reward, data + return 0, '' + +rs_trials = [] +for trial in range(args.num_trials): + print('### trial '+str(trial+1)+' ###') + split = "eval_out_of_distribution" + env = getattr(alfworld.agents.environment, config["env"]["type"])(config, train_eval=split) + env = env.init_env(batch_size=1) + + cnts = [0] * 6 + rs = [0] * 6 + rs_games = [] + if trial != 0: + memory = current_memory[:] + embeddings = generate_embeddings(memory) + current_memory = [] + for _ in range(134): + ob, info = env.reset() + ob = '\n'.join(ob[0].split('\n\n')[1:]) + name = '/'.join(info['extra.gamefile'][0].split('/')[-3:-1]) + print(name) + for i, (k, v) in enumerate(prefixes.items()): + if name.startswith(k): + if trial == 0: + prompt = 'Interact with a household to solve a task. Here are two examples.\n' + d_react[f'react_{v}_1'] + d_react[f'react_{v}_0'] + '\nHere is the task.\n' + r, mem_data = alfworld_run_react(prompt, ob, v) + if not mem_data=='': + current_memory.append(mem_data) + else: + r, mem_data = alfworld_run_rap('', ob, v, memory, embeddings) + if not mem_data=='': + current_memory.append(mem_data) + rs[i] += r + cnts[i] += 1 + break + rs_games.append(r) + print(_+1, 'r', r, 'rs', rs, 'cnts', cnts, 'sum(rs)/sum(cnts)', sum(rs) / sum(cnts)) + print('------------\n') + + rs_trials.append(rs_games) + rs_trials_max = np.max(np.array(rs_trials), axis=0) + print('trial:', trial+1, 'success rate:', np.sum(rs_trials_max) / rs_trials_max.shape[0]) + with open(args.output+'/memory_'+str(trial+1)+'.json', 'w') as f: + json.dump(current_memory, f, indent=4) +np.savetxt(args.output+'/result.txt', np.array(rs_trials).T, fmt='%d') diff --git a/alfworld/prompts/alfworld_3prompts.json b/alfworld/prompts/alfworld_3prompts.json new file mode 100644 index 0000000..0e7c204 --- /dev/null +++ b/alfworld/prompts/alfworld_3prompts.json @@ -0,0 +1 @@ +{"react_put_0": "You are in the middle of a room. Looking quickly around you, you see a cabinet 4, a cabinet 3, a cabinet 2, a cabinet 1, a countertop 1, a garbagecan 1, a handtowelholder 2, a handtowelholder 1, a sinkbasin 2, a sinkbasin 1, a toilet 1, a toiletpaperhanger 1, and a towelholder 1.\nYour task is to: put some spraybottle on toilet.\n> think: To solve the task, I need to find and take a sparybottle, then put it on toilet.\nOK.\n> think: First I need to find a spraybottle. A spraybottle is more likely to appear in cabinet (1-4), countertop (1), toilet (1), sinkbasin (1-2), garbagecan (1). I can check one by one, starting with cabinet 1.\nOK.\n> go to cabinet 1\nOn the cabinet 1, you see a cloth 1, a soapbar 1, a soapbottle 1.\n> go to cabinet 2\nThe cabinet 2 is closed.\n> open cabinet 2\nYou open the cabinet 2. The cabinet 2 is open. In it, you see a candle 1, and a spraybottle 2.\n> think: Now I find a spraybottle (2). Next, I need to take it.\n> take spraybottle 2 from cabinet 2\nYou pick up the spraybottle 2 from the cabinet 2.\n> think: Now I take a spraybottle (2). Next, I need to put it in/on toilet 1.\nOK.\n> go to toilet 1\nOn the toilet 1, you see a soapbottle 2.\n> put spraybottle 2 in/on toilet 1\nYou put the spraybottle 2 in/on the toilet 1.\n", "react_put_1": "You are in the middle of a room. Looking quickly around you, you see a cabinet 4, a cabinet 3, a cabinet 2, a cabinet 1, a coffeemachine 1, a countertop 1, a diningtable 3, a diningtable 2, a diningtable 1, a drawer 1, a fridge 1, a garbagecan 1, a microwave 1, a sidetable 1, a sinkbasin 1, a stoveburner 4, a stoveburner 3, a stoveburner 2, a stoveburner 1, and a toaster 1.\nYour task is to: find some apple and put it in sidetable.\n> think: To solve the task, I need to find and take an apple, then put it in sidetable.\nOK.\n> think: First I need to find an apple. An apple is more likely to appear in fridges (1), diningtables (1-3), sidetables (1), countertops (1), sinkbasins (1), garbagecan (1). I can check one by one, starting with fridge 1.\nOK.\n> go to fridge 1\nThe fridge 1 is closed.\n> open fridge 1\nYou open the fridge 1. The fridge 1 is open. In it, you see a lettuce 2, a mug 2, a potato 2, and a tomato 1.\n> go to diningtable 1\nOn the diningtable 1, you see nothing.\n> go to diningtable 2\nOn the diningtable 2, you see a pineapple 1.\n> go to diningtable 3\nOn the diningtable 3, you see a bowl 2, a bowl 1, a bread 2, and a bread 1.\n> go to sidetable 1\nOn the sidetable 1, you see a cup 1, a lettuce 1, a peppershaker 3, a potato 1, and a saltshaker 1.\n> go to countertop 1\nOn the countertop 1, you see a butterknife 1, a dishsponge 1, and a soapbottle 1.\n> go to sinkbasin 1\nOn the sinkbasin 1, you see a cup 2, a egg 1, a mug 1, and a potato 3.\n> go to garbagecan 1\nOn the garbagecan 1, you see a apple 3, and a egg 3.\n> think: Now I find an apple (3). Next, I need to take it.\n> take apple 3 from garbagecan 1\nYou pick up the apple 3 from the garbagecan 1.\n> think: Now I find an apple (3). Next, I need to put it in/on sidetable 1.\nOK.\n> go to sidetable 1\nOn the sidetable 1, you see a cup 1, a lettuce 1, a peppershaker 3, a potato 1, and a saltshaker 1.\n> put apple 3 in/on sidetable 1\nYou put the apple 3 in/on the sidetable 1.\n", "react_put_2": "You are in the middle of a room. Looking quickly around you, you see a bathtubbasin 1, a cabinet 4, a cabinet 3, a cabinet 2, a cabinet 1, a countertop 1, a drawer 4, a drawer 3, a drawer 2, a drawer 1, a dresser 1, a garbagecan 1, a handtowelholder 1, a sinkbasin 2, a sinkbasin 1, a toilet 1, a toiletpaperhanger 1, and a towelholder 1.\nYour task is to: put a soapbottle in garbagecan.\n> think: To solve the task, I need to find and take a soapbottle, and put it in garbagecan.\nOK.\n> think: First I need to find a soapbottle. A soapbottle is more likely to appear in toilet (1), sinkbasin (1-2), bathtubbasin (1), cabinet (1-4), countertop (1), dresser (1), drawer (1-4), garbagecan (1). I can check one by one, starting with toilet 1.\nOK.\n> go to toilet 1\nOn the toilet 1, you see nothing.\n> go to sinkbasin 1\nOn the sinkbasin 1, you see nothing.\n> go to sinkbasin 2\nOn the sinkbasin 2, you see nothing.\n> go to bathtubbasin 1\nOn the bathtubbasin 1, you see a cloth 2.\n> go to cabinet 1\nThe cabinet 1 is closed.\n> open cabinet 1\nYou open the cabinet 1. The cabinet 1 is open. In it, you see nothing.\n> go to cabinet 2\nThe cabinet 2 is closed.\n> open cabinet 2\nYou open the cabinet 2. The cabinet 2 is open. In it, you see nothing.\n> go to cabinet 3\nThe cabinet 3 is closed.\n> open cabinet 3\nYou open the cabinet 3. The cabinet 3 is open. In it, you see a toiletpaper 2.\n> go to cabinet 4\nThe cabinet 4 is closed.\n> open cabinet 4\nYou open the cabinet 4. The cabinet 4 is open. In it, you see a spraybottle 2.\n> go to countertop 1\nOn the countertop 1, you see a soapbottle 2, and a spraybottle 1.\n> think: Now I find a soapbottle (2). Next, I need to take it.\nOK.\n> take soapbottle 2 from countertop 1\nYou pick up the soapbottle 2 from the countertop 1.\n> think: Now I take a soapbottle (2). Next, I need to put it in/on garbagecan 1.\nOK.\n> go to garbagecan 1\nOn the garbagecan 1, you see nothing.\n> put soapbottle 2 in/on garbagecan 1\nYou put the soapbottle 2 in/on the garbagecan 1.\n", "react_clean_0": "You are in the middle of a room. Looking quickly around you, you see a cabinet 13, a cabinet 12, a cabinet 11, a cabinet 10, a cabinet 9, a cabinet 8, a cabinet 7, a cabinet 6, a cabinet 5, a cabinet 4, a cabinet 3, a cabinet 2, a cabinet 1, a coffeemachine 1, a countertop 1, a diningtable 1, a drawer 1, a fridge 1, a garbagecan 1, a microwave 1, a shelf 3, a shelf 2, a shelf 1, a sinkbasin 1, a stoveburner 4, a stoveburner 3, a stoveburner 2, a stoveburner 1, and a toaster 1.\nYour task is to: put a clean lettuce in diningtable.\n> think: To solve the task, I need to find and take a lettuce, then clean it with sinkbasin, then put it in diningtable. \nOK.\n> think: First I need to find a lettuce. A lettuce is more likely to appear in fridge (1), diningtable (1), sinkbasin (1), stoveburner (1-3), cabinet (1-13). I can check one by one, starting with fridge 1.\nOK.\n> go to fridge 1\nThe fridge 1 is closed.\n> open fridge 1\nYou open the fridge 1. The fridge 1 is open. In it, you see a cup 3, a egg 2, a potato 3, and a potato 2.\n> go to diningtable 1\nOn the diningtable 1, you see a apple 1, a bread 1, a butterknife 2, a cup 2, a fork 2, a knife 2, a knife 1, a ladle 1, a lettuce 1, a mug 2, a mug 1, a pan 2, a peppershaker 1, a spatula 3, a tomato 2, and a tomato 1.\n> think: Now I find a lettuce (1). Next, I need to take it.\nOK.\n> take lettuce 1 from diningtable 1\nYou pick up the lettuce 1 from the diningtable 1.\n> think: Now I take a lettuce (1). Next, I need to go to sinkbasin (1) and clean it.\nOK.\n> go to sinkbasin 1\nOn the sinkbasin 1, you see a apple 2, a ladle 2, a spoon 1, and a tomato 3.\n> clean lettuce 1 with sinkbasin 1\nYou clean the lettuce 1 using the sinkbasin 1.\n> think: Now I clean a lettuce (1). Next, I need to put it in/on diningtable 1.\nOK.\n> go to diningtable 1\nOn the diningtable 1, you see a apple 1, a bread 1, a butterknife 2, a cup 2, a fork 2, a knife 2, a knife 1, a ladle 1, a mug 2, a mug 1, a pan 2, a peppershaker 1, a spatula 3, a tomato 2, and a tomato 1.\n> put lettuce 1 in/on diningtable 1\nYou put the lettuce 1 in/on the diningtable 1.\n", "react_clean_1": "You are in the middle of a room. Looking quickly around you, you see a cabinet 4, a cabinet 3, a cabinet 2, a cabinet 1, a coffeemachine 1, a countertop 1, a diningtable 3, a diningtable 2, a diningtable 1, a drawer 1, a fridge 1, a garbagecan 1, a microwave 1, a sidetable 1, a sinkbasin 1, a stoveburner 4, a stoveburner 3, a stoveburner 2, a stoveburner 1, and a toaster 1.\nYour task is to: clean some apple and put it in sidetable.\n> think: To solve the task, I need to find and take an apple, then clean it with sinkbasin, then put it in sidetable.\nOK.\n> think: First I need to find an apple. An apple is more likely to appear in fridges (1), diningtable (1-3), sidetable (1), countertop (1), sinkbasin (1), garbagecan (1). I can check one by one, starting with fridge 1.\nOK.\n> go to fridge 1\nThe fridge 1 is closed.\n> open fridge 1\nYou open the fridge 1. The fridge 1 is open. In it, you see a lettuce 2, a mug 2, a potato 2, and a tomato 1.\n> go to diningtable 1\nOn the diningtable 1, you see nothing.\n> go to diningtable 2\nOn the diningtable 2, you see a pineapple 1.\n> go to diningtable 3\nOn the diningtable 3, you see a bowl 2, a bowl 1, a bread 2, and a bread 1.\n> go to sidetable 1\nOn the sidetable 1, you see a cup 1, a lettuce 1, a peppershaker 3, a potato 1, and a saltshaker 1.\n> go to countertop 1\nOn the countertop 1, you see a butterknife 1, a dishsponge 1, and a soapbottle 1.\n> go to sinkbasin 1\nOn the sinkbasin 1, you see a cup 2, a egg 1, a mug 1, and a potato 3.\n> go to garbagecan 1\nOn the garbagecan 1, you see a apple 3, and a egg 3.\n> think: Now I find an apple (3). Next, I need to take it.\nOK.\n> take apple 3 from garbagecan 1\nYou pick up the apple 3 from the garbagecan 1.\n> think: Now I take an apple (3). Next, I need to go to sinkbasin (1) and clean it.\nOK.\n> go to sinkbasin 1\nOn the sinkbasin 1, you see a cup 2, a egg 1, a mug 1, and a potato 3.\n> clean apple 3 with sinkbasin 1\nYou clean the apple 3 using the sinkbasin 1.\n> think: Now I clean an apple (3). Next, I need to put it in/on sidetable 1.\nOK.\n> go to sidetable 1\nOn the sidetable 1, you see a cup 1, a lettuce 1, a peppershaker 3, a potato 1, and a saltshaker 1.\n> put apple 3 in/on sidetable 1\nYou put the apple 3 in/on the sidetable 1.\n", "react_clean_2": "You are in the middle of a room. Looking quickly around you, you see a bathtubbasin 1, a garbagecan 1, a handtowelholder 1, a shelf 3, a shelf 2, a shelf 1, a sinkbasin 1, a toilet 1, a toiletpaperhanger 1, and a towelholder 1.\nYour task is to: clean some soapbar and put it in toilet.\n> think: To solve the task, I need to find and take a soapbar, then clean it with sinkbasin, then put it in toilet.\nOK.\n> think: First I need to find a soapbar. A soapbar is more likely to appear in toilet (1), bathtubbasin (1), sinkbasin (1), shelf (1-3), garbagecan (1). I can check one by one, starting with toilet 1.\nOK.\n> go to toilet 1\nOn the toilet 1, you see a soapbar 4, and a soapbar 3.\n> think: Now I find a soapbar (4). Next, I need to take it.\nOK.\n> take soapbar 4 from toilet 1\nYou pick up the soapbar 4 from the toilet 1.\n> think: Now I take a soapbar (4). Next, I need to go to sinkbasin (1) and clean it.\nOK.\n> go to sinkbasin 1\nOn the sinkbasin 1, you see nothing.\n> clean soapbar 4 with sinkbasin 1\nYou clean the soapbar 4 using the sinkbasin 1.\n> think: Now I clean a soapbar (4). Next, I need to put it in/on toilet 1.\nOK.\n> go to toilet 1\nOn the toilet 1, you see a soapbar 3.\n> put soapbar 4 in/on toilet 1\nYou put the soapbar 4 in/on the toilet 1.\n", "react_heat_0": "You are in the middle of a room. Looking quickly around you, you see a cabinet 10, a cabinet 9, a cabinet 8, a cabinet 7, a cabinet 6, a cabinet 5, a cabinet 4, a cabinet 3, a cabinet 2, a cabinet 1, a coffeemachine 1, a countertop 3, a countertop 2, a countertop 1, a diningtable 1, a drawer 6, a drawer 5, a drawer 4, a drawer 3, a drawer 2, a drawer 1, a fridge 1, a garbagecan 1, a microwave 1, a sinkbasin 1, a stoveburner 4, a stoveburner 3, a stoveburner 2, a stoveburner 1, and a toaster 1.\nYour task is to: heat some egg and put it in diningtable.\n> think: To solve the task, I need to find and take an egg, then heat it with microwave, then put it in diningtable.\nOK.\n> think: First I need to find an egg. An egg is more likely to appear in fridge (1), countertop (1-3), diningtable (1), stoveburner (1-4), toaster (1), garbagecan (1), cabinet (1-10). I can check one by one, starting with fridge 1.\nOK.\n> open fridge 1\nYou open the fridge 1. The fridge 1 is open. In it, you see a lettuce 2, a mug 2, and a potato 3.\n> go to countertop 1\nOn the countertop 1, you see a bread 1, a fork 1, and a saltshaker 1.\n> go to countertop 2\nOn the countertop 2, you see nothing.\n> go to countertop 3\nOn the countertop 3, you see a bowl 1, a butterknife 1, a egg 2, a kettle 2, a plate 1, a sink 1, and a spatula 2.\n> think: Now I find an egg (2). Next, I need to take it.\nOK.\n> take egg 2 from countertop 3\nYou pick up the egg 2 from the countertop 3.\n> think: Now I take an egg (2). Next, I need go to a microwave (1) and heat it.\nOK.\n> go to microwave 1\nThe microwave 1 is closed.\n> heat egg 2 with microwave 1\nYou heat the egg 2 using the microwave 1.\n> think: Now I heat an egg (2). Next, I need to put it in/on diningtable 1.\nOK.\n> go to diningtable 1\nOn the diningtable 1, you see a apple 2, a bread 3, a egg 1, a kettle 1, a knife 1, a mug 1, a papertowelroll 1, a peppershaker 2, a potato 1, a soapbottle 1, and a spatula 1.\n> put egg 2 in/on diningtable 1\nYou put the egg 2 in/on the diningtable 1.\n", "react_heat_1": "You are in the middle of a room. Looking quickly around you, you see a cabinet 13, a cabinet 12, a cabinet 11, a cabinet 10, a cabinet 9, a cabinet 8, a cabinet 7, a cabinet 6, a cabinet 5, a cabinet 4, a cabinet 3, a cabinet 2, a cabinet 1, a coffeemachine 1, a countertop 1, a diningtable 1, a drawer 1, a fridge 1, a garbagecan 1, a microwave 1, a shelf 3, a shelf 2, a shelf 1, a sinkbasin 1, a stoveburner 4, a stoveburner 3, a stoveburner 2, a stoveburner 1, and a toaster 1.\nYour task is to: put a hot apple in fridge.\n> think: To solve the task, I need to find and take an apple, then heat it with microwave, then put it in fridge.\nOK.\n> think: First I need to find an apple. An apple is more likely to appear in fridge (1), diningtable (1), coffeetable (1), drawer (1), cabinet (1-13), garbagecan (1). I can check one by one, starting with fridge 1.\nOK.\n> go to fridge 1\nThe fridge 1 is closed.\n> open fridge 1\nYou open the fridge 1. The fridge 1 is open. In it, you see a cup 1, and a egg 1.\n> go to diningtable 1\nOn the diningtable 1, you see a apple 1, a bread 1, a fork 3, a fork 2, a fork 1, a mug 2, a peppershaker 3, a plate 2, a pot 1, a soapbottle 3, a spatula 1, a spoon 3, a spoon 2, a spoon 1, a winebottle 3, and a winebottle 2.\n> think: Now I find an apple (1). Next, I need to take it.\nOK.\n> take apple 1 from diningtable 1\nYou pick up the apple 1 from the diningtable 1.\n> think: Now I take an apple (1). Next, I need to go to a microwave (1) and heat it.\nOK.\n> go to microwave 1\nThe microwave 1 is closed.\n> heat apple 1 with microwave 1\nYou heat the apple 1 using the microwave 1.\n> think: Now I heat an apple (1). Next, I need to put it in/on fridge 1.\nOK.\n> go to fridge 1\nThe fridge 1 is open. In it, you see a cup 1, and a egg 1.\n> put apple 1 in/on fridge 1\nYou put the apple 1 in/on the fridge 1.\n", "react_heat_2": "You are in the middle of a room. Looking quickly around you, you see a cabinet 11, a cabinet 10, a cabinet 9, a cabinet 8, a cabinet 7, a cabinet 6, a cabinet 5, a cabinet 4, a cabinet 3, a cabinet 2, a cabinet 1, a coffeemachine 1, a countertop 2, a countertop 1, a diningtable 1, a drawer 3, a drawer 2, a drawer 1, a fridge 1, a garbagecan 1, a microwave 1, a sinkbasin 1, a stoveburner 4, a stoveburner 3, a stoveburner 2, a stoveburner 1, and a toaster 1.\nYour task is to: heat some bread and put it in countertop.\n> think: To solve the task, I need to find and take a bread, then heat it with microwave, then put it in countertop.\nOK.\n> think: First I need to find a bread. A bread is more likely to appear in fridge (1), toaster (1), diningtable (1), countertop (1-2), drawer (1-3), cabinet (1-10). I can check one by one, starting with fridge 1.\nOK.\n> go to fridge 1\nThe fridge 1 is closed.\n> open fridge 1\nYou open the fridge 1. The fridge 1 is open. In it, you see a mug 3, and a mug 2.\n> go to toaster 1\nOn the toaster 1, you see nothing.\n> go to diningtable 1\nOn the diningtable 1, you see a bread 4, a bread 3, a bread 2, a bread 1, a cup 2, a knife 1, a lettuce 1, a potato 3, a tomato 3, a tomato 2, and a winebottle 3.\n> think: Now I find a bread (1). Next, I need to take it.\nOK.\n> take bread 1 from diningtable 1\nYou pick up the bread 1 from the diningtable 1.\n> think: Now I take a bread (1). Next, I need to go to a microwave (1) and heat it.\nOK.\n> go to microwave 1\nThe microwave 1 is closed.\n> heat bread 1 with microwave 1\nYou heat the bread 1 using the microwave 1.\n> think: Now I heat a bread (1). Next, I need to put it in/on countertop 1.\nOK.\n> go to countertop 1\nOn the countertop 1, you see a apple 1, a egg 1, a pan 2, a peppershaker 3, a plate 2, a plate 1, a soapbottle 1, and a winebottle 1.\n> put bread 1 in/on countertop 1\nYou put the bread 1 in/on the countertop 1.\n", "react_cool_0": "You are in the middle of a room. Looking quickly around you, you see a cabinet 16, a cabinet 15, a cabinet 14, a cabinet 13, a cabinet 12, a cabinet 11, a cabinet 10, a cabinet 9, a cabinet 8, a cabinet 7, a cabinet 6, a cabinet 5, a cabinet 4, a cabinet 3, a cabinet 2, a cabinet 1, a coffeemachine 1, a countertop 2, a countertop 1, a diningtable 1, a drawer 5, a drawer 4, a drawer 3, a drawer 2, a drawer 1, a fridge 1, a garbagecan 1, a microwave 1, a safe 1, a sinkbasin 1, a stoveburner 4, a stoveburner 3, a stoveburner 2, a stoveburner 1, and a toaster 1.\nYour task is to: cool some pan and put it in stoveburner.\n> think: To solve the task, I need to find and take a pan, then cool it with fridge, then put it in stoveburner.\nOK.\n> think: First I need to find a pan. An pan is more likely to appear in stoveburner (1-4), sinkbasin (1), diningtable (1), countertop (1-2), cabinet (1-16), drawer (1-5). I can check one by one, starting with stoveburner 1.\nOK.\n>go to stoveburner 1\nOn the stoveburner 1, you see nothing.\n>go to stoveburner 2\nOn the stoveburner 2, you see a pot 1.\n> go to stoveburner 3\nOn the stoveburner 3, you see a pan 1.\n> take pan 1 from stoveburner 3\n> think: Now I find a pan (1). Next, I need to take it.\nOK.\nYou pick up the pan 1 from the stoveburner 3.\n> think: Now I take a pan (1). Next, I need to go to a fridge (1) and cool it.\nOK.\n> go to fridge 1\nThe fridge 1 is closed.\n> cool pan 1 with fridge 1\nYou cool the pan 1 using the fridge 1.\n> think: Now I cool a pan (1). Next, I need to put it in/on stoveburner 1.\nOK.\n>go to stoveburner 1\nOn the stoveburner 1, you see nothing.\n> put pan 1 in/on stoveburner 1\nYou put the pan 1 in/on the stoveburner 1.\n", "react_cool_1": "You are in the middle of a room. Looking quickly around you, you see a cabinet 9, a cabinet 8, a cabinet 7, a cabinet 6, a cabinet 5, a cabinet 4, a cabinet 3, a cabinet 2, a cabinet 1, a coffeemachine 1, a countertop 3, a countertop 2, a countertop 1, a drawer 9, a drawer 8, a drawer 7, a drawer 6, a drawer 5, a drawer 4, a drawer 3, a drawer 2, a drawer 1, a fridge 1, a garbagecan 1, a microwave 1, a shelf 3, a shelf 2, a shelf 1, a sinkbasin 1, a stoveburner 4, a stoveburner 3, a stoveburner 2, a stoveburner 1, and a toaster 1.\nYour task is to: put a cool mug in shelf.\n> think: To solve the task, I need to find and take a mug, then cool it with fridge, then put it in shelf.\nOK.\n> think: First I need to find a mug. A mug is more likely to appear in countertop (1-3), coffeemachine (1), cabinet (1-9), shelf (1-3), drawer (1-9). I can check one by one, starting with countertop 1.\nOK.\n> go to countertop 1\nOn the countertop 1, you see a knife 1, a pan 2, a pan 1, and a plate 1.\n> go to countertop 2\nOn the countertop 2, you see a apple 2, a butterknife 2, a fork 3, a houseplant 1, a knife 2, a lettuce 3, a spatula 1, and a winebottle 1.\n> go to countertop 3\nOn the countertop 3, you see a apple 1, a book 1, a bread 1, a butterknife 3, a glassbottle 2, a glassbottle 1, a knife 3, a lettuce 2, a lettuce 1, a papertowelroll 1, a plate 3, a spoon 1, a statue 1, and a vase 2.\n> go to coffeemachine 1\nOn the coffeemachine 1, you see nothing.\n> go to cabinet 1\nThe cabinet 1 is closed.\n> open cabinet 1\nYou open the cabinet 1. The cabinet 1 is open. In it, you see nothing.\n> go to cabinet 2\nThe cabinet 2 is closed.\n> open cabinet 2\nYou open the cabinet 2. The cabinet 2 is open. In it, you see nothing.\n> go to cabinet 3\nThe cabinet 3 is closed.\n> open cabinet 3\nYou open the cabinet 3. The cabinet 3 is open. In it, you see a pot 1.\n> go to cabinet 4\nOn the cabinet 4, you see nothing.\n> go to cabinet 5\nThe cabinet 5 is closed.\n> open cabinet 5\nYou open the cabinet 5. The cabinet 5 is open. In it, you see nothing.\n> go to cabinet 6\nThe cabinet 6 is closed.\n> open cabinet 6\nYou open the cabinet 6. The cabinet 6 is open. In it, you see a mug 3.\n> think: Now I find a mug (3). Next, I need to take it.\nOK.\n> take mug 3 from cabinet 6\nYou pick up the mug 3 from the cabinet 6.\n> think: Now I take a mug (3). Next, I need to go to a fridge (1) and cool it.\nOK.\n> go to fridge 1\nThe fridge 1 is closed.\n> cool mug 3 with fridge 1\nYou cool the mug 3 using the fridge 1.\n> think: Now I cool the mug. Next, I need to put it in/on shelf 1.\nOK.\n> go to shelf 1\nOn the shelf 1, you see a cup 2, a cup 1, a peppershaker 1, and a saltshaker 1.\n> put mug 3 in/on shelf 1\nYou put the mug 3 in/on the shelf 1.\n", "react_cool_2": "You are in the middle of a room. Looking quickly around you, you see a cabinet 12, a cabinet 11, a cabinet 10, a cabinet 9, a cabinet 8, a cabinet 7, a cabinet 6, a cabinet 5, a cabinet 4, a cabinet 3, a cabinet 2, a cabinet 1, a coffeemachine 1, a countertop 2, a countertop 1, a diningtable 1, a drawer 3, a drawer 2, a drawer 1, a fridge 1, a garbagecan 1, a microwave 1, a sinkbasin 1, a stoveburner 4, a stoveburner 3, a stoveburner 2, a stoveburner 1, and a toaster 1.\nYour task is to: cool some potato and put it in diningtable.\n> think: To solve the task, I need to find and take a potato, then cool it with fridge, then put it in diningtable.\nOK.\n> think: First I need to find a potato. A potato is more likely to appear in fridge (1), diningtable (1), countertop (1-2), cabinet (1-12), drawer (1-3), garbagecan (1). I can check one by one, starting with fridge 1.\nOK.\n> go to fridge 1\nThe fridge 1 is closed.\n> open fridge 1\nYou open the fridge 1. The fridge 1 is open. In it, you see a apple 1, a bowl 1, a lettuce 2, and a lettuce 1.\n> go to diningtable 1\nOn the diningtable 1, you see a apple 3, a bread 1, a butterknife 3, a egg 2, a fork 1, a knife 2, a knife 1, a mug 1, a peppershaker 3, a plate 1, a potato 4, a potato 2, a saltshaker 2, a soapbottle 2, and a tomato 3.\n> think: Now I find a potato (2). Next, I need to take it.\nOK.\n> take potato 2 from diningtable 1\nYou pick up the potato 2 from the diningtable 1.\n> think: Now I take a potato (2). Next, I need to go to a fridge (1) and cool it.\nOK.\n> go to fridge 1\nThe fridge 1 is open. In it, you see a apple 1, a bowl 1, a lettuce 2, and a lettuce 1.\n> cool potato 2 with fridge 1\nYou cool the potato 2 using the fridge 1.\n> think: Now I cool a potato (2). Next, I need to put it in/on diningtable 1.\nOK.\n> go to diningtable 1\nOn the diningtable 1, you see a apple 3, a bread 1, a butterknife 3, a egg 2, a fork 1, a knife 2, a knife 1, a mug 1, a peppershaker 3, a plate 1, a potato 4, a saltshaker 2, a soapbottle 2, and a tomato 3.\n> put potato 2 in/on diningtable 1\nYou put the potato 2 in/on the diningtable 1.\n", "react_puttwo_0": "You are in the middle of a room. Looking quickly around you, you see a armchair 2, a armchair 1, a bed 1, a countertop 1, a diningtable 1, a drawer 2, a drawer 1, a dresser 1, a garbagecan 1, a laundryhamper 1, and a sidetable 1.\nYour task is to: put two creditcard in dresser.\n> think: To solve the task, I need to find and take the first creditcard, then put it in dresser, then find and take the second creditcard, then put it in dresser.\nOK.\n> think: First I need to find the first creditcard. A creditcard is more likely to appear in drawer (1-2), coutertop (1), sidetable (1), diningtable (1), armchair (1-2), bed (1). I can check one by one, starting with drawer 1.\nOK.\n> go to drawer 1\nThe drawer 1 is closed.\n> open drawer 1\nYou open the drawer 1. The drawer 1 is open. In it, you see a book 1, a cd 1, and a pen 1.\n> go to drawer 2\nThe drawer 2 is closed.\n> open drawer 2\nYou open the drawer 2. The drawer 2 is open. In it, you see nothing.\n> go to countertop 1\nOn the countertop 1, you see a cellphone 2, a creditcard 4, a creditcard 3, a creditcard 2, a mirror 1, a pencil 2, and a pencil 1.\n> think: Now I find the first creditcard (2). Next, I need to take it. I can find the second creditcard (3) later in countertop 1.\nOK.\n> take creditcard 2 from countertop 1\nYou pick up the creditcard 2 from the countertop 1.\n> think: Now I take the first creditcard (2). Next, I need to put it in/on dresser 1.\nOK.\n> go to dresser 1\nOn the dresser 1, you see a mug 1, and a television 1.\n> put creditcard 2 in/on dresser 1\nYou put the creditcard 2 in/on the dresser 1.\n> think: Now I put the first creditcard in dresser. Next, I need to find the second creditcard. I can directly go to countertop 1.\nOK.\n> go to countertop 1\nOn the countertop 1, you see a cellphone 2, a creditcard 4, a creditcard 3, a mirror 1, a pencil 2, and a pencil 1.\n> think: Now I find the second creditcard (3). Next, I need to take it.\nOK.\n> take creditcard 3 from countertop 1\nYou pick up the creditcard 3 from the countertop 1.\n> think: Now I take the second creditcard (3). Next, I need to put it in/on dresser 1.\nOK.\n> go to dresser 1\nOn the dresser 1, you see a creditcard 2, a mug 1, and a television 1.\n> put creditcard 3 in/on dresser 1\nYou put the creditcard 3 in/on the dresser 1.\n", "react_puttwo_1": "You are in the middle of a room. Looking quickly around you, you see a coffeetable 1, a diningtable 1, a drawer 4, a drawer 3, a drawer 2, a drawer 1, a dresser 1, a garbagecan 1, a sidetable 2, a sidetable 1, and a sofa 1.\nYour task is to: put two cellphone in sofa.\n> think: To solve the task, I need to find and take the first cellphone, then put it in sofa, then find and take the second cellphone, then put it in sofa.\nOK.\n> think: First I need to find the first cellphone. A cellphone is more likely to appear in coffeetable (1), diningtable (1), sidetable (1-2), drawer (1-4), sofa (1), dresser (1), garbagecan (1). I can check one by one, starting with coffeetable 1.\nOK.\n> go to coffeetable 1\nOn the coffeetable 1, you see a box 1, a cellphone 3, and a plate 1.\n> take cellphone 3 from coffeetable 1\nYou pick up the cellphone 3 from the coffeetable 1.\n> think: Now I find the first cellphone (3). Next, I need to put it in/on sofa 1.\nOK.\n> go to sofa 1\nOn the sofa 1, you see a newspaper 2, a pillow 1, a remotecontrol 2, and a remotecontrol 1.\n> put cellphone 3 in/on sofa 1\nYou put the cellphone 3 in/on the sofa 1.\n> think: Now I put the first cellphone in sofa. Next, I need to find the second cellphone. I have visited coffeetable (1), so the second cellphone is more likely to appear in diningtable (1), sidetable (1-2), drawer (1-4), sofa (1), dresser (1), garbagecan (1). I can check one by one, starting with coffeetable 1.\nOK.\n> go to diningtable 1\nOn the diningtable 1, you see a cellphone 2, a keychain 2, a laptop 1, a statue 2, and a statue 1.\n> think: Now I find the second cellphone (2). Next, I need to take it.\nOK.\n> take cellphone 2 from diningtable 1\nYou pick up the cellphone 2 from the diningtable 1.\n> think: Now I take the second cellphone (2). Next, I need to put it in/on sofa 1.\nOK.\n> go to sofa 1\nOn the sofa 1, you see a cellphone 3, a newspaper 2, a pillow 1, a remotecontrol 2, and a remotecontrol 1.\n> put cellphone 2 in/on sofa 1\nYou put the cellphone 2 in/on the sofa 1.\n", "react_puttwo_2": "You are in the middle of a room. Looking quickly around you, you see a cabinet 20, a cabinet 19, a cabinet 18, a cabinet 17, a cabinet 16, a cabinet 15, a cabinet 14, a cabinet 13, a cabinet 12, a cabinet 11, a cabinet 10, a cabinet 9, a cabinet 8, a cabinet 7, a cabinet 6, a cabinet 5, a cabinet 4, a cabinet 3, a cabinet 2, a cabinet 1, a coffeemachine 1, a countertop 3, a countertop 2, a countertop 1, a drawer 3, a drawer 2, a drawer 1, a fridge 1, a garbagecan 1, a microwave 1, a shelf 3, a shelf 2, a shelf 1, a sinkbasin 1, a stoveburner 4, a stoveburner 3, a stoveburner 2, a stoveburner 1, and a toaster 1.\nYour task is to: put two saltshaker in drawer.\n> think: To solve the task, I need to find and take the first saltshaker, then put it in drawer, then find and take the second salkshaker, then put it in drawer.\nOK.\n> think: First I need to find the first saltshaker. A saltshaker is more likely to appear in drawer (1-3), countertop (1-3), shelf (1-3), cabinet (1-20). I can check one by one, starting with drawer 1.\nOK.\n> go to drawer 1\nThe drawer 1 is closed.\n> open drawer 1\nYou open the drawer 1. The drawer 1 is open. In it, you see nothing.\n> go to drawer 2\nThe drawer 2 is closed.\n> open drawer 2\nYou open the drawer 2. The drawer 2 is open. In it, you see a dishsponge 3.\n> go to drawer 3\nThe drawer 3 is closed.\n> open drawer 3\nYou open the drawer 3. The drawer 3 is open. In it, you see a fork 2, a ladle 2, and a spoon 1.\n> go to countertop 1\nOn the countertop 1, you see a bowl 1, a butterknife 1, a mug 2, a pan 1, a papertowelroll 1, a spatula 1, and a statue 3.\n> go to countertop 2\nOn the countertop 2, you see a bread 1, a butterknife 2, a dishsponge 2, a fork 1, a kettle 1, a knife 1, a ladle 1, a spatula 3, a spoon 2, a statue 2, and a vase 3.\n> go to countertop 3\nOn the countertop 3, you see a bowl 2, a houseplant 1, a knife 2, a peppershaker 1, a saltshaker 4, a soapbottle 1, a spatula 2, and a tomato 3.\n> think: Now I find the first saltshaker (4). Next, I need to take it.\nOK.\n> take saltshaker 4 from countertop 3\nYou pick up the saltshaker 4 from the countertop 3.\n> think: Now I take the first saltshaker (4). Next, I need to put it in/on drawer 1.\nOK.\n> go to drawer 1\nThe drawer 1 is open. In it, you see nothing.\n> put saltshaker 4 in/on drawer 1\nYou put the saltshaker 4 in/on the drawer 1.\n> think: Now I put the first saltshaker in drawer. Next, I need to find the second saltshaker. I have visited drawer (1-3), countertop (1-3), so the second saltshaker is more likely to appear in shelf (1-3), cabinet (1-20). I can check one by one, starting with shelf 1.\nOK.\n> go to shelf 1\nOn the shelf 1, you see a statue 1.\n> go to shelf 2\nOn the shelf 2, you see a dishsponge 1, and a vase 1.\n> go to shelf 3\nOn the shelf 3, you see nothing.\n> go to cabinet 1\nThe cabinet 1 is closed.\n> open cabinet 1\nYou open the cabinet 1. The cabinet 1 is open. In it, you see nothing.\n> go to cabinet 2\nNothing happens.\n> look\nYou are facing the cabinet 2, and cabinet 1. Next to it, you see nothing.\n> go to cabinet 3\nThe cabinet 3 is closed.\n> open cabinet 3\nYou open the cabinet 3. The cabinet 3 is open. In it, you see a saltshaker 3, and a saltshaker 2.\n> think: Now I find the second saltshaker (2). Next, I need to take it.\nOK.\n> take saltshaker 2 from cabinet 3\nYou pick up the saltshaker 2 from the cabinet 3.\n> think: Now I take the second saltshaker (2). Next, I need to put it in/on drawer 1.\nOK.\n> go to drawer 1\nThe drawer 1 is open. In it, you see a saltshaker 4.\n> put saltshaker 2 in/on drawer 1\nYou put the saltshaker 2 in/on the drawer 1.\n", "react_examine_0": "You are in the middle of a room. Looking quickly around you, you see a bed 1, a desk 1, a drawer 3, a drawer 2, a drawer 1, a garbagecan 1, a safe 1, a shelf 5, a shelf 4, a shelf 3, a shelf 2, a shelf 1, a sidetable 2, and a sidetable 1.\nYour task is to: look at bowl under the desklamp.\n> think: To solve the task, I need to find and take a bowl, then find and use a desklamp. \nOK. \n> think: First I need to find a bowl. A bowl is more likely to appear in drawer (1-3), desk (1), sidetable (1-2), shelf (1-5), garbagecan (1). I can check one by one, starting with drawer 1.\nOK.\n> go to drawer 1\nOn the drawer 1, you see nothing.\n> go to drawer 2\nThe drawer 2 is closed.\n> open drawer 2\nYou open the drawer 2. The drawer 2 is open. In it, you see nothing.\n> go to drawer 3\nThe drawer 3 is closed.\n> open drawer 3\nYou open the drawer 3. The drawer 3 is open. In it, you see nothing.\n> go to desk 1\nOn the desk 1, you see a alarmclock 2, a book 1, a cellphone 1, a keychain 1, a laptop 2, a laptop 1, and a pen 3.\n> go to sidetable 1\nOn the sidetable 1, you see a cd 1, a pen 1, and a pencil 1.\n> go to shelf 1\nOn the shelf 1, you see nothing.\n> go to shelf 2\nOn the shelf 2, you see a bowl 1.\n> think: Now I find a bowl (1). Next, I need to take it.\nOK.\n> take bowl 1 from shelf 2\nYou pick up the bowl 1 from the shelf 2.\n> think: Now I take a bowl (1). Next, I need to find a desklamp. A desklamp is more likely to appear in desk (1), sidetable (1-2), shelf (1-5), bed (1), drawer (1-3). I can check one by one, starting with desk 1.\nOK.\n> go to desk 1\nOn the desk 1, you see a alarmclock 2, a book 1, a cellphone 1, a keychain 1, a laptop 2, a laptop 1, and a pen 3.\n> go to sidetable 1\nOn the sidetable 1, you see a cd 1, a pen 1, and a pencil 1.\n> go to sidetable 2\nOn the sidetable 2, you see a alarmclock 1, a desklamp 1, and a pen 2.\n> think: Now I find a desklamp (1). Next, I need to use it.\nOK.\n> use desklamp 1\nYou turn on the desklamp 1.\n", "react_examine_1": "You are in the middle of a room. Looking quickly around you, you see a bed 1, a drawer 10, a drawer 9, a drawer 8, a drawer 7, a drawer 6, a drawer 5, a drawer 4, a drawer 3, a drawer 2, a drawer 1, a dresser 1, a garbagecan 1, a shelf 9, a shelf 8, a shelf 7, a shelf 6, a shelf 5, a shelf 4, a shelf 3, a shelf 2, and a shelf 1.\nYour task is to: examine the pen with the desklamp.\n> think: To solve the task, I need to find and take a pen, then find and use a desklamp. First I need to find a pen. A pen is more likely to appear in drawer (1-10), shelf (1-9), bed (1), garbagecan (1). I can check one by one, starting with drawer 1.\nOK.\n> go to drawer 1\nThe drawer 1 is closed.\n> open drawer 1\nYou open the drawer 1. The drawer 1 is open. In it, you see nothing.\n> go to drawer 2\nThe drawer 2 is closed.\n> open drawer 2\nYou open the drawer 2. The drawer 2 is open. In it, you see nothing.\n> go to drawer 3\nThe drawer 3 is closed.\n> open drawer 3\nYou open the drawer 3. The drawer 3 is open. In it, you see nothing.\n> go to drawer 4\nThe drawer 4 is closed.\n> open drawer 4\nYou open the drawer 4. The drawer 4 is open. In it, you see a cd 3, a keychain 1, and a pen 2.\n> think: Now I find a pen (2). Next, I need to take it.\nOK.\n> take pen 2 from drawer 4\nYou pick up the pen 2 from the drawer 4.\n> think: Now I take a pen (2). Next, I need to find a desklamp. A desklamp is more likely to appear in dresser (1), shelf (1-9), bed (1), garbagecan (1), drawer (1-10). I can check one by one, starting with dresser 1.\nOK.\n> go to dresser 1\nOn the dresser 1, you see a alarmclock 2, a alarmclock 1, a book 1, a cd 1, a creditcard 1, a desklamp 1, a keychain 2, a pen 3, and a pen 1.\n> think: Now I find a desklamp (1). Next, I need to use it.\nOK.\n> use desklamp 1\nYou turn on the desklamp 1.\n", "react_examine_2": "You are in the middle of a room. Looking quickly around you, you see a coffeetable 1, a diningtable 1, a drawer 4, a drawer 3, a drawer 2, a drawer 1, a dresser 1, a garbagecan 1, a sidetable 2, a sidetable 1, and a sofa 1.\nYour task is to: look at statue under the desklamp.\n> think: To solve the task, I need to find and take a statue, then find and use a desklamp.\nOK.\n> think: First I need to find a statue. A statue is more likely to appear in dresser (1), coffeetable (1), sidetable (1-2), diningtable (1), sofa (1), garbagecan (1). I can check one by one, starting with dresser 1.\nOK.\n> go to dresser 1\nOn the dresser 1, you see a cellphone 3, a newspaper 2, a statue 1, and a television 1.\n> think: Now I find a statue (1). Next, I need to take it.\nOK.\n> take statue 1 from dresser 1\nYou pick up the statue 1 from the dresser 1.\n> think: Now I take a statue (1). Next, I need to find a desklamp. A desklamp is more likely to appear in sidetable (1-2), coffeetable (1), diningtable (1). I can check one by one, starting with sidetable 1.\nOK.\n> go to sidetable 1\nOn the sidetable 1, you see nothing.\n> go to sidetable 2\nOn the sidetable 2, you see a desklamp 3, a newspaper 1, and a statue 2.\n> think: Now I find a desklamp (3). Next, I need to use it.\nOK.\n> use desklamp 3\nYou turn on the desklamp 3.\n", "act_put_0": "You are in the middle of a room. Looking quickly around you, you see a cabinet 4, a cabinet 3, a cabinet 2, a cabinet 1, a countertop 1, a garbagecan 1, a handtowelholder 2, a handtowelholder 1, a sinkbasin 2, a sinkbasin 1, a toilet 1, a toiletpaperhanger 1, and a towelholder 1.\nYour task is to: put some spraybottle on toilet.\n> go to cabinet 1\nOn the cabinet 1, you see a cloth 1, a soapbar 1, a soapbottle 1.\n> go to cabinet 2\nThe cabinet 2 is closed.\n> open cabinet 2\nYou open the cabinet 2. The cabinet 2 is open. In it, you see a candle 1, and a spraybottle 2.\n> take spraybottle 2 from cabinet 2\nYou pick up the spraybottle 2 from the cabinet 2.\n> go to toilet 1\nOn the toilet 1, you see a soapbottle 2.\n> put spraybottle 2 in/on toilet 1\nYou put the spraybottle 2 in/on the toilet 1.\n", "act_put_1": "You are in the middle of a room. Looking quickly around you, you see a cabinet 4, a cabinet 3, a cabinet 2, a cabinet 1, a coffeemachine 1, a countertop 1, a diningtable 3, a diningtable 2, a diningtable 1, a drawer 1, a fridge 1, a garbagecan 1, a microwave 1, a sidetable 1, a sinkbasin 1, a stoveburner 4, a stoveburner 3, a stoveburner 2, a stoveburner 1, and a toaster 1.\nYour task is to: find some apple and put it in sidetable.\n> go to fridge 1\nThe fridge 1 is closed.\n> open fridge 1\nYou open the fridge 1. The fridge 1 is open. In it, you see a lettuce 2, a mug 2, a potato 2, and a tomato 1.\n> go to diningtable 1\nOn the diningtable 1, you see nothing.\n> go to diningtable 2\nOn the diningtable 2, you see a pineapple 1.\n> go to diningtable 3\nOn the diningtable 3, you see a bowl 2, a bowl 1, a bread 2, and a bread 1.\n> go to sidetable 1\nOn the sidetable 1, you see a cup 1, a lettuce 1, a peppershaker 3, a potato 1, and a saltshaker 1.\n> go to countertop 1\nOn the countertop 1, you see a butterknife 1, a dishsponge 1, and a soapbottle 1.\n> go to sinkbasin 1\nOn the sinkbasin 1, you see a cup 2, a egg 1, a mug 1, and a potato 3.\n> go to garbagecan 1\nOn the garbagecan 1, you see a apple 3, and a egg 3.\n> take apple 3 from garbagecan 1\nYou pick up the apple 3 from the garbagecan 1.\n> go to sidetable 1\nOn the sidetable 1, you see a cup 1, a lettuce 1, a peppershaker 3, a potato 1, and a saltshaker 1.\n> put apple 3 in/on sidetable 1\nYou put the apple 3 in/on the sidetable 1.\n", "act_put_2": "You are in the middle of a room. Looking quickly around you, you see a bathtubbasin 1, a cabinet 4, a cabinet 3, a cabinet 2, a cabinet 1, a countertop 1, a drawer 4, a drawer 3, a drawer 2, a drawer 1, a dresser 1, a garbagecan 1, a handtowelholder 1, a sinkbasin 2, a sinkbasin 1, a toilet 1, a toiletpaperhanger 1, and a towelholder 1.\nYour task is to: put a soapbottle in garbagecan.\n> go to toilet 1\nOn the toilet 1, you see nothing.\n> go to sinkbasin 1\nOn the sinkbasin 1, you see nothing.\n> go to sinkbasin 2\nOn the sinkbasin 2, you see nothing.\n> go to bathtubbasin 1\nOn the bathtubbasin 1, you see a cloth 2.\n> go to cabinet 1\nThe cabinet 1 is closed.\n> open cabinet 1\nYou open the cabinet 1. The cabinet 1 is open. In it, you see nothing.\n> go to cabinet 2\nThe cabinet 2 is closed.\n> open cabinet 2\nYou open the cabinet 2. The cabinet 2 is open. In it, you see nothing.\n> go to cabinet 3\nThe cabinet 3 is closed.\n> open cabinet 3\nYou open the cabinet 3. The cabinet 3 is open. In it, you see a toiletpaper 2.\n> go to cabinet 4\nThe cabinet 4 is closed.\n> open cabinet 4\nYou open the cabinet 4. The cabinet 4 is open. In it, you see a spraybottle 2.\n> go to countertop 1\nOn the countertop 1, you see a soapbottle 2, and a spraybottle 1.\n> take soapbottle 2 from countertop 1\nYou pick up the soapbottle 2 from the countertop 1.\n> go to garbagecan 1\nOn the garbagecan 1, you see nothing.\n> put soapbottle 2 in/on garbagecan 1\nYou put the soapbottle 2 in/on the garbagecan 1.\n", "act_clean_0": "You are in the middle of a room. Looking quickly around you, you see a cabinet 13, a cabinet 12, a cabinet 11, a cabinet 10, a cabinet 9, a cabinet 8, a cabinet 7, a cabinet 6, a cabinet 5, a cabinet 4, a cabinet 3, a cabinet 2, a cabinet 1, a coffeemachine 1, a countertop 1, a diningtable 1, a drawer 1, a fridge 1, a garbagecan 1, a microwave 1, a shelf 3, a shelf 2, a shelf 1, a sinkbasin 1, a stoveburner 4, a stoveburner 3, a stoveburner 2, a stoveburner 1, and a toaster 1.\nYour task is to: put a clean lettuce in diningtable.\n> go to fridge 1\nThe fridge 1 is closed.\n> open fridge 1\nYou open the fridge 1. The fridge 1 is open. In it, you see a cup 3, a egg 2, a potato 3, and a potato 2.\n> go to diningtable 1\nOn the diningtable 1, you see a apple 1, a bread 1, a butterknife 2, a cup 2, a fork 2, a knife 2, a knife 1, a ladle 1, a lettuce 1, a mug 2, a mug 1, a pan 2, a peppershaker 1, a spatula 3, a tomato 2, and a tomato 1.\n> take lettuce 1 from diningtable 1\nYou pick up the lettuce 1 from the diningtable 1.\n> go to sinkbasin 1\nOn the sinkbasin 1, you see a apple 2, a ladle 2, a spoon 1, and a tomato 3.\n> clean lettuce 1 with sinkbasin 1\nYou clean the lettuce 1 using the sinkbasin 1.\n> go to diningtable 1\nOn the diningtable 1, you see a apple 1, a bread 1, a butterknife 2, a cup 2, a fork 2, a knife 2, a knife 1, a ladle 1, a mug 2, a mug 1, a pan 2, a peppershaker 1, a spatula 3, a tomato 2, and a tomato 1.\n> put lettuce 1 in/on diningtable 1\nYou put the lettuce 1 in/on the diningtable 1.\n", "act_clean_1": "You are in the middle of a room. Looking quickly around you, you see a cabinet 4, a cabinet 3, a cabinet 2, a cabinet 1, a coffeemachine 1, a countertop 1, a diningtable 3, a diningtable 2, a diningtable 1, a drawer 1, a fridge 1, a garbagecan 1, a microwave 1, a sidetable 1, a sinkbasin 1, a stoveburner 4, a stoveburner 3, a stoveburner 2, a stoveburner 1, and a toaster 1.\nYour task is to: clean some apple and put it in sidetable.\n> go to fridge 1\nThe fridge 1 is closed.\n> open fridge 1\nYou open the fridge 1. The fridge 1 is open. In it, you see a lettuce 2, a mug 2, a potato 2, and a tomato 1.\n> go to diningtable 1\nOn the diningtable 1, you see nothing.\n> go to diningtable 2\nOn the diningtable 2, you see a pineapple 1.\n> go to diningtable 3\nOn the diningtable 3, you see a bowl 2, a bowl 1, a bread 2, and a bread 1.\n> go to sidetable 1\nOn the sidetable 1, you see a cup 1, a lettuce 1, a peppershaker 3, a potato 1, and a saltshaker 1.\n> go to countertop 1\nOn the countertop 1, you see a butterknife 1, a dishsponge 1, and a soapbottle 1.\n> go to sinkbasin 1\nOn the sinkbasin 1, you see a cup 2, a egg 1, a mug 1, and a potato 3.\n> go to garbagecan 1\nOn the garbagecan 1, you see a apple 3, and a egg 3.\n> take apple 3 from garbagecan 1\nYou pick up the apple 3 from the garbagecan 1.\n> go to sinkbasin 1\nOn the sinkbasin 1, you see a cup 2, a egg 1, a mug 1, and a potato 3.\n> clean apple 3 with sinkbasin 1\nYou clean the apple 3 using the sinkbasin 1.\n> go to sidetable 1\nOn the sidetable 1, you see a cup 1, a lettuce 1, a peppershaker 3, a potato 1, and a saltshaker 1.\n> put apple 3 in/on sidetable 1\nYou put the apple 3 in/on the sidetable 1.\n", "act_clean_2": "You are in the middle of a room. Looking quickly around you, you see a bathtubbasin 1, a garbagecan 1, a handtowelholder 1, a shelf 3, a shelf 2, a shelf 1, a sinkbasin 1, a toilet 1, a toiletpaperhanger 1, and a towelholder 1.\nYour task is to: clean some soapbar and put it in toilet.\n> go to toilet 1\nOn the toilet 1, you see a soapbar 4, and a soapbar 3.\n> take soapbar 4 from toilet 1\nYou pick up the soapbar 4 from the toilet 1.\n> go to sinkbasin 1\nOn the sinkbasin 1, you see nothing.\n> clean soapbar 4 with sinkbasin 1\nYou clean the soapbar 4 using the sinkbasin 1.\n> go to toilet 1\nOn the toilet 1, you see a soapbar 3.\n> put soapbar 4 in/on toilet 1\nYou put the soapbar 4 in/on the toilet 1.\n", "act_heat_0": "You are in the middle of a room. Looking quickly around you, you see a cabinet 10, a cabinet 9, a cabinet 8, a cabinet 7, a cabinet 6, a cabinet 5, a cabinet 4, a cabinet 3, a cabinet 2, a cabinet 1, a coffeemachine 1, a countertop 3, a countertop 2, a countertop 1, a diningtable 1, a drawer 6, a drawer 5, a drawer 4, a drawer 3, a drawer 2, a drawer 1, a fridge 1, a garbagecan 1, a microwave 1, a sinkbasin 1, a stoveburner 4, a stoveburner 3, a stoveburner 2, a stoveburner 1, and a toaster 1.\nYour task is to: heat some egg and put it in diningtable.\n> open fridge 1\nYou open the fridge 1. The fridge 1 is open. In it, you see a lettuce 2, a mug 2, and a potato 3.\n> go to countertop 1\nOn the countertop 1, you see a bread 1, a fork 1, and a saltshaker 1.\n> go to countertop 2\nOn the countertop 2, you see nothing.\n> go to countertop 3\nOn the countertop 3, you see a bowl 1, a butterknife 1, a egg 2, a kettle 2, a plate 1, a sink 1, and a spatula 2.\n> take egg 2 from countertop 3\nYou pick up the egg 2 from the countertop 3.\n> go to microwave 1\nThe microwave 1 is closed.\n> heat egg 2 with microwave 1\nYou heat the egg 2 using the microwave 1.\n> go to diningtable 1\nOn the diningtable 1, you see a apple 2, a bread 3, a egg 1, a kettle 1, a knife 1, a mug 1, a papertowelroll 1, a peppershaker 2, a potato 1, a soapbottle 1, and a spatula 1.\n> put egg 2 in/on diningtable 1\nYou put the egg 2 in/on the diningtable 1.\n", "act_heat_1": "You are in the middle of a room. Looking quickly around you, you see a cabinet 13, a cabinet 12, a cabinet 11, a cabinet 10, a cabinet 9, a cabinet 8, a cabinet 7, a cabinet 6, a cabinet 5, a cabinet 4, a cabinet 3, a cabinet 2, a cabinet 1, a coffeemachine 1, a countertop 1, a diningtable 1, a drawer 1, a fridge 1, a garbagecan 1, a microwave 1, a shelf 3, a shelf 2, a shelf 1, a sinkbasin 1, a stoveburner 4, a stoveburner 3, a stoveburner 2, a stoveburner 1, and a toaster 1.\nYour task is to: put a hot apple in fridge.\n> go to fridge 1\nThe fridge 1 is closed.\n> open fridge 1\nYou open the fridge 1. The fridge 1 is open. In it, you see a cup 1, and a egg 1.\n> go to diningtable 1\nOn the diningtable 1, you see a apple 1, a bread 1, a fork 3, a fork 2, a fork 1, a mug 2, a peppershaker 3, a plate 2, a pot 1, a soapbottle 3, a spatula 1, a spoon 3, a spoon 2, a spoon 1, a winebottle 3, and a winebottle 2.\n> take apple 1 from diningtable 1\nYou pick up the apple 1 from the diningtable 1.\n> go to microwave 1\nThe microwave 1 is closed.\n> heat apple 1 with microwave 1\nYou heat the apple 1 using the microwave 1.\n> go to fridge 1\nThe fridge 1 is open. In it, you see a cup 1, and a egg 1.\n> put apple 1 in/on fridge 1\nYou put the apple 1 in/on the fridge 1.\n", "act_heat_2": "You are in the middle of a room. Looking quickly around you, you see a cabinet 11, a cabinet 10, a cabinet 9, a cabinet 8, a cabinet 7, a cabinet 6, a cabinet 5, a cabinet 4, a cabinet 3, a cabinet 2, a cabinet 1, a coffeemachine 1, a countertop 2, a countertop 1, a diningtable 1, a drawer 3, a drawer 2, a drawer 1, a fridge 1, a garbagecan 1, a microwave 1, a sinkbasin 1, a stoveburner 4, a stoveburner 3, a stoveburner 2, a stoveburner 1, and a toaster 1.\nYour task is to: heat some bread and put it in countertop.\n> go to fridge 1\nThe fridge 1 is closed.\n> open fridge 1\nYou open the fridge 1. The fridge 1 is open. In it, you see a mug 3, and a mug 2.\n> go to toaster 1\nOn the toaster 1, you see nothing.\n> go to diningtable 1\nOn the diningtable 1, you see a bread 4, a bread 3, a bread 2, a bread 1, a cup 2, a knife 1, a lettuce 1, a potato 3, a tomato 3, a tomato 2, and a winebottle 3.\n> take bread 1 from diningtable 1\nYou pick up the bread 1 from the diningtable 1.\n> go to microwave 1\nThe microwave 1 is closed.\n> heat bread 1 with microwave 1\nYou heat the bread 1 using the microwave 1.\n> go to countertop 1\nOn the countertop 1, you see a apple 1, a egg 1, a pan 2, a peppershaker 3, a plate 2, a plate 1, a soapbottle 1, and a winebottle 1.\n> put bread 1 in/on countertop 1\nYou put the bread 1 in/on the countertop 1.\n", "act_cool_0": "You are in the middle of a room. Looking quickly around you, you see a cabinet 16, a cabinet 15, a cabinet 14, a cabinet 13, a cabinet 12, a cabinet 11, a cabinet 10, a cabinet 9, a cabinet 8, a cabinet 7, a cabinet 6, a cabinet 5, a cabinet 4, a cabinet 3, a cabinet 2, a cabinet 1, a coffeemachine 1, a countertop 2, a countertop 1, a diningtable 1, a drawer 5, a drawer 4, a drawer 3, a drawer 2, a drawer 1, a fridge 1, a garbagecan 1, a microwave 1, a safe 1, a sinkbasin 1, a stoveburner 4, a stoveburner 3, a stoveburner 2, a stoveburner 1, and a toaster 1.\nYour task is to: cool some pan and put it in stoveburner.\n>go to stoveburner 1\nOn the stoveburner 1, you see nothing.\n>go to stoveburner 2\nOn the stoveburner 2, you see a pot 1.\n> go to stoveburner 3\nOn the stoveburner 3, you see a pan 1.\n> take pan 1 from stoveburner 3\nYou pick up the pan 1 from the stoveburner 3.\n> go to fridge 1\nThe fridge 1 is closed.\n> cool pan 1 with fridge 1\nYou cool the pan 1 using the fridge 1.\n>go to stoveburner 1\nOn the stoveburner 1, you see nothing.\n> put pan 1 in/on stoveburner 1\nYou put the pan 1 in/on the stoveburner 1.\n", "act_cool_1": "You are in the middle of a room. Looking quickly around you, you see a cabinet 9, a cabinet 8, a cabinet 7, a cabinet 6, a cabinet 5, a cabinet 4, a cabinet 3, a cabinet 2, a cabinet 1, a coffeemachine 1, a countertop 3, a countertop 2, a countertop 1, a drawer 9, a drawer 8, a drawer 7, a drawer 6, a drawer 5, a drawer 4, a drawer 3, a drawer 2, a drawer 1, a fridge 1, a garbagecan 1, a microwave 1, a shelf 3, a shelf 2, a shelf 1, a sinkbasin 1, a stoveburner 4, a stoveburner 3, a stoveburner 2, a stoveburner 1, and a toaster 1.\nYour task is to: put a cool mug in shelf.\n> go to countertop 1\nOn the countertop 1, you see a knife 1, a pan 2, a pan 1, and a plate 1.\n> go to countertop 2\nOn the countertop 2, you see a apple 2, a butterknife 2, a fork 3, a houseplant 1, a knife 2, a lettuce 3, a spatula 1, and a winebottle 1.\n> go to countertop 3\nOn the countertop 3, you see a apple 1, a book 1, a bread 1, a butterknife 3, a glassbottle 2, a glassbottle 1, a knife 3, a lettuce 2, a lettuce 1, a papertowelroll 1, a plate 3, a spoon 1, a statue 1, and a vase 2.\n> go to coffeemachine 1\nOn the coffeemachine 1, you see nothing.\n> go to cabinet 1\nThe cabinet 1 is closed.\n> open cabinet 1\nYou open the cabinet 1. The cabinet 1 is open. In it, you see nothing.\n> go to cabinet 2\nThe cabinet 2 is closed.\n> open cabinet 2\nYou open the cabinet 2. The cabinet 2 is open. In it, you see nothing.\n> go to cabinet 3\nThe cabinet 3 is closed.\n> open cabinet 3\nYou open the cabinet 3. The cabinet 3 is open. In it, you see a pot 1.\n> go to cabinet 4\nOn the cabinet 4, you see nothing.\n> go to cabinet 5\nThe cabinet 5 is closed.\n> open cabinet 5\nYou open the cabinet 5. The cabinet 5 is open. In it, you see nothing.\n> go to cabinet 6\nThe cabinet 6 is closed.\n> open cabinet 6\nYou open the cabinet 6. The cabinet 6 is open. In it, you see a mug 3.\n> take mug 3 from cabinet 6\nYou pick up the mug 3 from the cabinet 6.\n> go to fridge 1\nThe fridge 1 is closed.\n> cool mug 3 with fridge 1\nYou cool the mug 3 using the fridge 1.\n> go to shelf 1\nOn the shelf 1, you see a cup 2, a cup 1, a peppershaker 1, and a saltshaker 1.\n> put mug 3 in/on shelf 1\nYou put the mug 3 in/on the shelf 1.\n", "act_cool_2": "You are in the middle of a room. Looking quickly around you, you see a cabinet 12, a cabinet 11, a cabinet 10, a cabinet 9, a cabinet 8, a cabinet 7, a cabinet 6, a cabinet 5, a cabinet 4, a cabinet 3, a cabinet 2, a cabinet 1, a coffeemachine 1, a countertop 2, a countertop 1, a diningtable 1, a drawer 3, a drawer 2, a drawer 1, a fridge 1, a garbagecan 1, a microwave 1, a sinkbasin 1, a stoveburner 4, a stoveburner 3, a stoveburner 2, a stoveburner 1, and a toaster 1.\nYour task is to: cool some potato and put it in diningtable.\n> go to fridge 1\nThe fridge 1 is closed.\n> open fridge 1\nYou open the fridge 1. The fridge 1 is open. In it, you see a apple 1, a bowl 1, a lettuce 2, and a lettuce 1.\n> go to diningtable 1\nOn the diningtable 1, you see a apple 3, a bread 1, a butterknife 3, a egg 2, a fork 1, a knife 2, a knife 1, a mug 1, a peppershaker 3, a plate 1, a potato 4, a potato 2, a saltshaker 2, a soapbottle 2, and a tomato 3.\n> take potato 2 from diningtable 1\nYou pick up the potato 2 from the diningtable 1.\n> go to fridge 1\nThe fridge 1 is open. In it, you see a apple 1, a bowl 1, a lettuce 2, and a lettuce 1.\n> cool potato 2 with fridge 1\nYou cool the potato 2 using the fridge 1.\n> go to diningtable 1\nOn the diningtable 1, you see a apple 3, a bread 1, a butterknife 3, a egg 2, a fork 1, a knife 2, a knife 1, a mug 1, a peppershaker 3, a plate 1, a potato 4, a saltshaker 2, a soapbottle 2, and a tomato 3.\n> put potato 2 in/on diningtable 1\nYou put the potato 2 in/on the diningtable 1.\n", "act_puttwo_0": "You are in the middle of a room. Looking quickly around you, you see a armchair 2, a armchair 1, a bed 1, a countertop 1, a diningtable 1, a drawer 2, a drawer 1, a dresser 1, a garbagecan 1, a laundryhamper 1, and a sidetable 1.\nYour task is to: put two creditcard in dresser.\n> go to drawer 1\nThe drawer 1 is closed.\n> open drawer 1\nYou open the drawer 1. The drawer 1 is open. In it, you see a book 1, a cd 1, and a pen 1.\n> go to drawer 2\nThe drawer 2 is closed.\n> open drawer 2\nYou open the drawer 2. The drawer 2 is open. In it, you see nothing.\n> go to countertop 1\nOn the countertop 1, you see a cellphone 2, a creditcard 4, a creditcard 3, a creditcard 2, a mirror 1, a pencil 2, and a pencil 1.\n> take creditcard 2 from countertop 1\nYou pick up the creditcard 2 from the countertop 1.\n> go to dresser 1\nOn the dresser 1, you see a mug 1, and a television 1.\n> put creditcard 2 in/on dresser 1\nYou put the creditcard 2 in/on the dresser 1.\n> go to countertop 1\nOn the countertop 1, you see a cellphone 2, a creditcard 4, a creditcard 3, a mirror 1, a pencil 2, and a pencil 1.\n> take creditcard 3 from countertop 1\nYou pick up the creditcard 3 from the countertop 1.\n> go to dresser 1\nOn the dresser 1, you see a creditcard 2, a mug 1, and a television 1.\n> put creditcard 3 in/on dresser 1\nYou put the creditcard 3 in/on the dresser 1.\n", "act_puttwo_1": "You are in the middle of a room. Looking quickly around you, you see a coffeetable 1, a diningtable 1, a drawer 4, a drawer 3, a drawer 2, a drawer 1, a dresser 1, a garbagecan 1, a sidetable 2, a sidetable 1, and a sofa 1.\nYour task is to: put two cellphone in sofa.\n> go to coffeetable 1\nOn the coffeetable 1, you see a box 1, a cellphone 3, and a plate 1.\n> take cellphone 3 from coffeetable 1\nYou pick up the cellphone 3 from the coffeetable 1.\n> go to sofa 1\nOn the sofa 1, you see a newspaper 2, a pillow 1, a remotecontrol 2, and a remotecontrol 1.\n> put cellphone 3 in/on sofa 1\nYou put the cellphone 3 in/on the sofa 1.\n> go to diningtable 1\nOn the diningtable 1, you see a cellphone 2, a keychain 2, a laptop 1, a statue 2, and a statue 1.\n> take cellphone 2 from diningtable 1\nYou pick up the cellphone 2 from the diningtable 1.\n> go to sofa 1\nOn the sofa 1, you see a cellphone 3, a newspaper 2, a pillow 1, a remotecontrol 2, and a remotecontrol 1.\n> put cellphone 2 in/on sofa 1\nYou put the cellphone 2 in/on the sofa 1.\n", "act_puttwo_2": "You are in the middle of a room. Looking quickly around you, you see a cabinet 20, a cabinet 19, a cabinet 18, a cabinet 17, a cabinet 16, a cabinet 15, a cabinet 14, a cabinet 13, a cabinet 12, a cabinet 11, a cabinet 10, a cabinet 9, a cabinet 8, a cabinet 7, a cabinet 6, a cabinet 5, a cabinet 4, a cabinet 3, a cabinet 2, a cabinet 1, a coffeemachine 1, a countertop 3, a countertop 2, a countertop 1, a drawer 3, a drawer 2, a drawer 1, a fridge 1, a garbagecan 1, a microwave 1, a shelf 3, a shelf 2, a shelf 1, a sinkbasin 1, a stoveburner 4, a stoveburner 3, a stoveburner 2, a stoveburner 1, and a toaster 1.\nYour task is to: put two saltshaker in drawer.\n> go to drawer 1\nThe drawer 1 is closed.\n> open drawer 1\nYou open the drawer 1. The drawer 1 is open. In it, you see nothing.\n> go to drawer 2\nThe drawer 2 is closed.\n> open drawer 2\nYou open the drawer 2. The drawer 2 is open. In it, you see a dishsponge 3.\n> go to drawer 3\nThe drawer 3 is closed.\n> open drawer 3\nYou open the drawer 3. The drawer 3 is open. In it, you see a fork 2, a ladle 2, and a spoon 1.\n> go to countertop 1\nOn the countertop 1, you see a bowl 1, a butterknife 1, a mug 2, a pan 1, a papertowelroll 1, a spatula 1, and a statue 3.\n> go to countertop 2\nOn the countertop 2, you see a bread 1, a butterknife 2, a dishsponge 2, a fork 1, a kettle 1, a knife 1, a ladle 1, a spatula 3, a spoon 2, a statue 2, and a vase 3.\n> go to countertop 3\nOn the countertop 3, you see a bowl 2, a houseplant 1, a knife 2, a peppershaker 1, a saltshaker 4, a soapbottle 1, a spatula 2, and a tomato 3.\n> take saltshaker 4 from countertop 3\nYou pick up the saltshaker 4 from the countertop 3.\n> go to drawer 1\nThe drawer 1 is open. In it, you see nothing.\n> put saltshaker 4 in/on drawer 1\nYou put the saltshaker 4 in/on the drawer 1.\n> go to shelf 1\nOn the shelf 1, you see a statue 1.\n> go to shelf 2\nOn the shelf 2, you see a dishsponge 1, and a vase 1.\n> go to shelf 3\nOn the shelf 3, you see nothing.\n> go to cabinet 1\nThe cabinet 1 is closed.\n> open cabinet 1\nYou open the cabinet 1. The cabinet 1 is open. In it, you see nothing.\n> go to cabinet 2\nNothing happens.\n> look\nYou are facing the cabinet 2, and cabinet 1. Next to it, you see nothing.\n> go to cabinet 3\nThe cabinet 3 is closed.\n> open cabinet 3\nYou open the cabinet 3. The cabinet 3 is open. In it, you see a saltshaker 3, and a saltshaker 2.\n> take saltshaker 2 from cabinet 3\nYou pick up the saltshaker 2 from the cabinet 3.\n> go to drawer 1\nThe drawer 1 is open. In it, you see a saltshaker 4.\n> put saltshaker 2 in/on drawer 1\nYou put the saltshaker 2 in/on the drawer 1.\n", "act_examine_0": "You are in the middle of a room. Looking quickly around you, you see a bed 1, a desk 1, a drawer 3, a drawer 2, a drawer 1, a garbagecan 1, a safe 1, a shelf 5, a shelf 4, a shelf 3, a shelf 2, a shelf 1, a sidetable 2, and a sidetable 1.\nYour task is to: look at bowl under the desklamp.\nOK. \n> go to drawer 1\nOn the drawer 1, you see nothing.\n> go to drawer 2\nThe drawer 2 is closed.\n> open drawer 2\nYou open the drawer 2. The drawer 2 is open. In it, you see nothing.\n> go to drawer 3\nThe drawer 3 is closed.\n> open drawer 3\nYou open the drawer 3. The drawer 3 is open. In it, you see nothing.\n> go to desk 1\nOn the desk 1, you see a alarmclock 2, a book 1, a cellphone 1, a keychain 1, a laptop 2, a laptop 1, and a pen 3.\n> go to sidetable 1\nOn the sidetable 1, you see a cd 1, a pen 1, and a pencil 1.\n> go to shelf 1\nOn the shelf 1, you see nothing.\n> go to shelf 2\nOn the shelf 2, you see a bowl 1.\n> take bowl 1 from shelf 2\nYou pick up the bowl 1 from the shelf 2.\n> go to desk 1\nOn the desk 1, you see a alarmclock 2, a book 1, a cellphone 1, a keychain 1, a laptop 2, a laptop 1, and a pen 3.\n> go to sidetable 1\nOn the sidetable 1, you see a cd 1, a pen 1, and a pencil 1.\n> go to sidetable 2\nOn the sidetable 2, you see a alarmclock 1, a desklamp 1, and a pen 2.\n> use desklamp 1\nYou turn on the desklamp 1.\n", "act_examine_1": "You are in the middle of a room. Looking quickly around you, you see a bed 1, a drawer 10, a drawer 9, a drawer 8, a drawer 7, a drawer 6, a drawer 5, a drawer 4, a drawer 3, a drawer 2, a drawer 1, a dresser 1, a garbagecan 1, a shelf 9, a shelf 8, a shelf 7, a shelf 6, a shelf 5, a shelf 4, a shelf 3, a shelf 2, and a shelf 1.\nYour task is to: examine the pen with the desklamp.\n> go to drawer 1\nThe drawer 1 is closed.\n> open drawer 1\nYou open the drawer 1. The drawer 1 is open. In it, you see nothing.\n> go to drawer 2\nThe drawer 2 is closed.\n> open drawer 2\nYou open the drawer 2. The drawer 2 is open. In it, you see nothing.\n> go to drawer 3\nThe drawer 3 is closed.\n> open drawer 3\nYou open the drawer 3. The drawer 3 is open. In it, you see nothing.\n> go to drawer 4\nThe drawer 4 is closed.\n> open drawer 4\nYou open the drawer 4. The drawer 4 is open. In it, you see a cd 3, a keychain 1, and a pen 2.\n> take pen 2 from drawer 4\nYou pick up the pen 2 from the drawer 4.\n> go to dresser 1\nOn the dresser 1, you see a alarmclock 2, a alarmclock 1, a book 1, a cd 1, a creditcard 1, a desklamp 1, a keychain 2, a pen 3, and a pen 1.\n> use desklamp 1\nYou turn on the desklamp 1.\n", "act_examine_2": "You are in the middle of a room. Looking quickly around you, you see a coffeetable 1, a diningtable 1, a drawer 4, a drawer 3, a drawer 2, a drawer 1, a dresser 1, a garbagecan 1, a sidetable 2, a sidetable 1, and a sofa 1.\nYour task is to: look at statue under the desklamp.\n> go to dresser 1\nOn the dresser 1, you see a cellphone 3, a newspaper 2, a statue 1, and a television 1.\n> take statue 1 from dresser 1\nYou pick up the statue 1 from the dresser 1.\n> go to sidetable 1\nOn the sidetable 1, you see nothing.\n> go to sidetable 2\nOn the sidetable 2, you see a desklamp 3, a newspaper 1, and a statue 2.\n> use desklamp 3\nYou turn on the desklamp 3.\n"} \ No newline at end of file diff --git a/alfworld/prompts/retrieval_prompt.txt b/alfworld/prompts/retrieval_prompt.txt new file mode 100644 index 0000000..a1a5a1b --- /dev/null +++ b/alfworld/prompts/retrieval_prompt.txt @@ -0,0 +1,28 @@ +think: First I need to find a spraybottle. A spraybottle is more likely to appear in cabinet (1-4), countertop (1), toilet (1), sinkbasin (1-2), garbagecan (1). I can check one by one, starting with cabinet 1. +> search: spraybottle +think: Now I put the first creditcard in dresser. Next, I need to find the second creditcard. I can directly go to countertop 1. +> search: creditcard +think: Now I take a pen (2). Next, I need to find a desklamp. A desklamp is more likely to appear in dresser (1), shelf (1-9), bed (1), garbagecan (1), drawer (1-10). I can check one by one, starting with dresser 1. +> search: desklamp +think: Now I find a lettuce (1). Next, I need to take it. +> action: take +think: Now I find a pan (1). Next, I need to take it. +> action: take +think: Now I find the second saltshaker (2). Next, I need to take it. +> action: take +think: Now I heat an egg (2). Next, I need to put it in/on diningtable 1. +> action: put +think: Now I take a spraybottle (2). Next, I need to put it in/on toilet 1. +> action: put +think: Now I take an apple (1). Next, I need to go to a microwave (1) and heat it. +> action: heat +think: Now I take a bread (1). Next, I need to go to a microwave (1) and heat it. +> action: heat +think: Now I take a mug (3). Next, I need to go to a fridge (1) and cool it. +> action: cool +think: Now I take a potato (2). Next, I need to go to a fridge (1) and cool it. +> action: cool +think: Now I find a desklamp (1). Next, I need to use it. +> action: use +think: Now I find a desklamp (3). Next, I need to use it. +> action: use diff --git a/alfworld/requirements.txt b/alfworld/requirements.txt new file mode 100644 index 0000000..a27334c --- /dev/null +++ b/alfworld/requirements.txt @@ -0,0 +1,9 @@ +alfworld==0.3.4 +openai==1.30.5 +PyYAML==6.0.1 +sentence_transformers==2.2.2 +torch==2.0.1 +torchvision==0.15.2 +transformers==4.41.1 +bitsandbytes==0.43.1 +accelerate==0.30.1 diff --git a/figure/figure.png b/figure/figure.png new file mode 100644 index 0000000..21d68e8 Binary files /dev/null and b/figure/figure.png differ diff --git a/webshop/README.md b/webshop/README.md new file mode 100644 index 0000000..2f13f5a --- /dev/null +++ b/webshop/README.md @@ -0,0 +1,51 @@ +# Get Started +1. Move webshop directory and install requirements +```bash +pip install -r requirements.txt +``` + +2. According to the [instruction](https://github.com/princeton-nlp/WebShop?tab=readme-ov-file#-setup), download the data, setup the webserver and set environment variables + +* Note: host webserver and all data on localhost as provided web-link (http://3.83.245.205:3000) by Webshop is not valid. + +
+ +> Note: Alternative setup procedure for steps 1 and 2: +> * Install full list of requirements, merged with WebShop +> +> ```bash +> pip install -r merged_requirements.txt +> ``` +> +> * Execute SpaCy download +> ```bash +> python -m spacy download en_core_web_lg +> ``` +> +> * Clone the WebShop repository from [here](https://github.com/princeton-nlp/WebShop) +> * Download all necessary data specified in WebShop + +
+ +3. Run (in a **separate** terminal) the webserver. (Note: Stop/terminate and restart the webserver before each experiment.) +```bash +cd +./run_dev.sh +``` + +4. Prepare OpenAI API key and put the key in ```OpenAI_api_key.txt``` + +5. Run RAP on Webshop +```bash +python main.py +``` + +Following are the hyper-parametes for RAP. + +* num_trials: Number of recursive trials. Default is 3. +* num_steps: Maximum steps in one task. Default is 50. +* model: Model to be used in evaluation. Default is "gpt-3.5-turbo-instruct". +* output: Folder path to output logs and memory. +* emb_model: Embedding model to be used in evaluation. Default is "sentence-transformers/all-MiniLM-L6-v2". + +Also, Python 3.8.10 is recommended for evaluation. (Note: Current hard requirement of Python 3.8 due to incompatibility issues of pyserini/nmslib with python >= 3.9) \ No newline at end of file diff --git a/webshop/configs/base_config.yaml b/webshop/configs/base_config.yaml new file mode 100644 index 0000000..4366c09 --- /dev/null +++ b/webshop/configs/base_config.yaml @@ -0,0 +1,12 @@ +params: + initial_prompt: 'PROMPT1' + temperature: 0.0 + split: 'final' + success: True + query_category: True + intra_task: True + act_obs: True + analogy_len: 10 + num_retrieval: 3 + reward_weight: 1 + max_init_prompt_len: 6400 diff --git a/webshop/main.py b/webshop/main.py new file mode 100644 index 0000000..b9f0550 --- /dev/null +++ b/webshop/main.py @@ -0,0 +1,606 @@ +import os,sys +import yaml +import json +import numpy as np +import transformers +import torch +import argparse + +parser = argparse.ArgumentParser() +parser.add_argument("--num_trials", type=int, default=3, help="The number of trials") +parser.add_argument("--num_steps", type=int, default=15, help="The number of steps") +parser.add_argument("--model", type=str, default="gpt-3.5-turbo-instruct", choices=["gpt-3.5-turbo-instruct", "gpt-4-0613", "meta-llama/Llama-2-13b-chat-hf"], help="The model name") +parser.add_argument("--output", type=str, default="output", help="The output folder") +parser.add_argument("--emb_model", type=str, default="sentence-transformers/all-MiniLM-L6-v2", choices=["sentence-transformers/all-MiniLM-L6-v2", "sentence-transformers/all-MiniLM-L12-v2"], help="The model name") +args = parser.parse_args() + +os.makedirs(args.output, exist_ok=True) + +with open('./configs/base_config.yaml') as reader: + config = yaml.safe_load(reader) + +# llama2 +from transformers import AutoModelForCausalLM +from transformers import AutoTokenizer + +if 'Llama-2' in args.model or any(map(args.model.__contains__, AutoModelForCausalLM._model_mapping._model_mapping)): + model_name = args.model + model = AutoModelForCausalLM.from_pretrained( + model_name, load_in_4bit=True, device_map="auto" + ) + tokenizer = AutoTokenizer.from_pretrained(model_name) + + pipeline = transformers.pipeline( + "text-generation", + model=model, + tokenizer=tokenizer, + ) +elif 'gpt' in args.model: + #openai + import openai + from openai import OpenAI + os.environ["OPENAI_API_KEY"] = open('OpenAI_api_key.txt').readline() + openai.api_key = os.environ["OPENAI_API_KEY"] + client = OpenAI() +else: + print('LLM currently not supported') + sys.exit(0) + + + +def llm(prompt, stop=["\n"]): + + if 'Llama-2' in args.model: + sequences = pipeline( + prompt, + do_sample=config['params'].get('temperature', 1) > 0, # True, + top_k=10, + num_return_sequences=1, + eos_token_id=tokenizer.eos_token_id, + max_new_tokens=200, + temperature=config['params'].get('temperature', 1), + return_full_text=False, + ) + text = sequences[0]['generated_text'] + elif 'gpt-3.5-turbo-instruct' == args.model: + response = client.completions.create( + model='gpt-3.5-turbo-instruct', + prompt=prompt, + temperature=config['params'].get('temperature', 0), + max_tokens=100, + top_p=1, + frequency_penalty=0.0, + presence_penalty=0.0, + stop=stop + ) + text = response.choices[0].text + elif 'gpt-4-0613' == args.model: + completion = client.chat.completions.create( + model="gpt-4-0613", + messages=[ + {"role": "system", "content": "You are a helpful assistant for household task."}, + {"role": "user", "content": prompt}, + ], + temperature=0.5, + max_tokens=100, + top_p=1, + frequency_penalty=0.0, + presence_penalty=0.0, + stop=stop + ) + text = completion.choices[0].message.content + + if stop: + text = text.split('\n')[0] + if len(text) > 0 and text[0]=='>': + text = text[1:] + if len(text) > 0 and text[-1]=='.': + text = text[:-1] + return text.strip() + + +WEBSHOP_URL = f"http://localhost:3000/" + + +''' Setting up webshop environment''' +import requests +from bs4 import BeautifulSoup +from bs4.element import Comment + +ACTION_TO_TEMPLATE = { + 'Description': 'description_page.html', + 'Features': 'features_page.html', + 'Reviews': 'review_page.html', + 'Attributes': 'attributes_page.html', +} + +def clean_str(p): + return p.encode().decode("unicode-escape").encode("latin1").decode("utf-8") + + +def tag_visible(element): + ignore = {'style', 'script', 'head', 'title', 'meta', '[document]'} + return ( + element.parent.name not in ignore and not isinstance(element, Comment) + ) + + +def webshop_text(session, page_type, query_string='', page_num=1, asin='', options={}, subpage='', **kwargs): + if page_type == 'init': + url = ( + f'{WEBSHOP_URL}/{session}' + ) + if page_type == 'search': + url = ( + f'{WEBSHOP_URL}/search_results/{session}/' + f'{query_string}/{page_num}' + ) + elif page_type == 'item': + url = ( + f'{WEBSHOP_URL}/item_page/{session}/' + f'{asin}/{query_string}/{page_num}/{options}' + ) + elif page_type == 'item_sub': + url = ( + f'{WEBSHOP_URL}/item_sub_page/{session}/' + f'{asin}/{query_string}/{page_num}/{subpage}/{options}' + ) + elif page_type == 'end': + url = ( + f'{WEBSHOP_URL}/done/{session}/' + f'{asin}/{options}' + ) + html = requests.get(url).text + html_obj = BeautifulSoup(html, 'html.parser') + texts = html_obj.findAll(text=True) + visible_texts = list(filter(tag_visible, texts)) + # visible_texts = [str(text).strip().strip('\\n') for text in visible_texts] + # if page_type == 'end': import pdb; pdb.set_trace() + if False: + # For `simple` mode, return just [SEP] separators + return ' [SEP] '.join(t.strip() for t in visible_texts if t != '\n') + else: + # Otherwise, return an observation with tags mapped to specific, unique separators + observation = '' + option_type = '' + options = {} + asins = [] + cnt = 0 + prod_cnt = 0 + just_prod = 0 + for t in visible_texts: + if t == '\n': continue + if t.replace('\n', '').replace('\\n', '').replace(' ', '') == '': continue + # if t.startswith('Instruction:') and page_type != 'init': continue + if t.parent.name == 'button': # button + processed_t = f'\n[{t}] ' + elif t.parent.name == 'label': # options + if f"'{t}'" in url: + processed_t = f'[[{t}]]' + # observation = f'You have clicked {t}.\n' + observation + else: + processed_t = f'[{t}]' + options[str(t)] = option_type + # options[option_type] = options.get(option_type, []) + [str(t)] + elif t.parent.get('class') == ["product-link"]: # product asins + processed_t = f'\n[{t}] ' + if prod_cnt >= 3: + processed_t = '' + prod_cnt += 1 + asins.append(str(t)) + just_prod = 0 + else: # regular, unclickable text + processed_t = '\n' + str(t) + ' ' + if cnt < 2 and page_type != 'init': processed_t = '' + if just_prod <= 2 and prod_cnt >= 4: processed_t = '' + option_type = str(t) + cnt += 1 + just_prod += 1 + observation += processed_t + info = {} + if options: + info['option_types'] = options + if asins: + info['asins'] = asins + if 'Your score (min 0.0, max 1.0)' in visible_texts: + idx = visible_texts.index('Your score (min 0.0, max 1.0)') + info['reward'] = float(visible_texts[idx + 1]) + observation = 'Your score (min 0.0, max 1.0): ' + (visible_texts[idx + 1]) + # Retrieve images available on webpage + if page_type == 'search' or page_type == 'item': + info['img'] = list(filter(tag_visible, html_obj.findAll(lambda tag: (tag.name == 'img' and tag.has_attr('src'))))) + # Get starting instruction text + instruction = html_obj.find(id='instruction-text') + if instruction is not None: + instruction = instruction.h4 + if instruction is not None: + instruction = instruction.text + else: + instruction = html_obj.find(id='goal-instruction-text') + if instruction is not None: + instruction = instruction.pre + if instruction is not None: + instruction = instruction.text + info['instruction'] = instruction #if instruction is not None else '' + query = html_obj.find(id='goal-query') + if query is not None: + query = query.pre + if query is not None: + query = query.text + info['query'] = query if query is not None else '' + category = html_obj.find(id='goal-category') + if category is not None: + category = category.pre + if category is not None: + category = category.text + info['category'] = category if category is not None else '' + return clean_str(observation), info + + +from urllib.parse import quote +class webshopEnv: + def __init__(self): + self.sessions = {} + + def step(self, session, action): + done = False + observation_ = None + if action == 'reset': + self.sessions[session] = {'session': session, 'page_type': 'init'} + elif action.startswith('think['): + observation = 'OK.' + elif action.startswith('search['): + assert self.sessions[session]['page_type'] == 'init' + query = action[7:-1] + self.sessions[session] = {'session': session, 'page_type': 'search', + 'query_string': query, 'page_num': 1} + elif action.startswith('click['): + button = action[6:-1] + if button == 'Buy Now': + assert self.sessions[session]['page_type'] == 'item' + # Help URI Encoding, as WSGI error thrown when option has '#' + if 'options' in self.sessions[session]: + for option_type in self.sessions[session]['options']: + self.sessions[session]['options'][option_type] = quote(self.sessions[session]['options'][option_type]) + self.sessions[session]['page_type'] = 'end' + done = True + elif button == 'Back to Search': + assert self.sessions[session]['page_type'] in ['search', 'item_sub', 'item'] + self.sessions[session] = {'session': session, 'page_type': 'init'} + elif button == 'Next >': + assert False # ad hoc page limitation + assert self.sessions[session]['page_type'] == 'search' + self.sessions[session]['page_num'] += 1 + elif button == '< Prev': + assert self.sessions[session]['page_type'] in ['search', 'item_sub', 'item'] + if self.sessions[session]['page_type'] == 'search': + assert False + self.sessions[session]['page_num'] -= 1 + elif self.sessions[session]['page_type'] == 'item_sub': + self.sessions[session]['page_type'] = 'item' + elif self.sessions[session]['page_type'] == 'item': + self.sessions[session]['page_type'] = 'search' + self.sessions[session]['options'] = {} + elif button in ACTION_TO_TEMPLATE: + assert self.sessions[session]['page_type'] == 'item' + self.sessions[session]['page_type'] = 'item_sub' + self.sessions[session]['subpage'] = button + else: + if self.sessions[session]['page_type'] == 'search': + assert button in self.sessions[session].get('asins', []) # must be asins + self.sessions[session]['page_type'] = 'item' + self.sessions[session]['asin'] = button + elif self.sessions[session]['page_type'] == 'item': + assert 'option_types' in self.sessions[session] + assert button in self.sessions[session]['option_types'], (button, self.sessions[session]['option_types']) # must be options + option_type = self.sessions[session]['option_types'][button] + if not 'options' in self.sessions[session]: + self.sessions[session]['options'] = {} + self.sessions[session]['options'][option_type] = button + observation_ = f'You have clicked {button}.' + else: + assert False + observation, info = webshop_text(**self.sessions[session]) + if observation_: + observation = observation_ + self.sessions[session].update(info) + reward = info.get('reward', 0.0) + return observation, reward, done, info + +env = webshopEnv() + + +# text embedding model +from sentence_transformers import SentenceTransformer +from sentence_transformers.util import cos_sim +model_embedding = SentenceTransformer(args.emb_model) + +from prompts.webshop_prompt import * +initial_prompt = INITIAL_PROMPTS[config['params'].get('initial_prompt', 'PROMPT1')] + +def generate_embeddings(memory): + memory = [m for m in memory if m['Reward'] > 0.0] + if config['params'].get('success', False): + memory = [m for m in memory if m['Success']] + print('num_retrieval',len(memory)) + embeddings = {} + for key in ['Instruction', 'Reward', 'Category', 'Query', 'Actions']: + if key=='Actions' and 'Actions' in memory[0]: + retrieve_info = [m[key][1:].copy() for m in memory] + for i in range(len(retrieve_info)): + for j in range(len(retrieve_info[i])): + retrieve_info[i][j] = retrieve_info[i][j].strip() + embeddings[key] = [model_embedding.encode(r) for r in retrieve_info] + continue + retrieve_info = [m[key] for m in memory] + if key=='Reward': + embeddings[key] = retrieve_info + continue + # extract embeddings + embeddings[key] = model_embedding.encode(retrieve_info) + return embeddings + + +def generate_examples(info, actions, memory, embeddings, reasoning='', k=3, act_len=0, use_act_obs=False): + cos_scores=None + # retrieve examples + if info.get('instruction', None) is not None: + instruction = info['instruction'] + with torch.no_grad(): + instruction_embedding = model_embedding.encode([instruction]) + cos_scores = cos_sim(instruction_embedding, embeddings['Instruction'])[0] + if config['params'].get('query_category', False): + cos_scores += cos_sim(instruction_embedding, embeddings['Query'])[0] + if not config['params'].get('success', False): + cos_scores += (torch.tensor(embeddings['Reward']) * config['params'].get('reward_weight', 1)) + + if len(actions) > 2 and (actions[-2].replace('Action: ', '').startswith('think') or actions[-2].replace('Action: ', '').startswith('search')): + reasoning = actions[-2].replace('Action: ', '') + if cos_scores is not None: + if act_len > 0 and reasoning != '' and 'Actions' in embeddings: + ret_scores, ret_index, intra_scores = [], [], [] + query_embedding = model_embedding.encode([reasoning]) + for a, emb in enumerate(embeddings['Actions']): + if use_act_obs: + if actions[-2].replace('Action: ', '').startswith('think'): + #print('ret word act:',actions[-2].replace('Action: ', '')) + query_embedding = model_embedding.encode([actions[-2].replace('Action: ', '')]) + cos_scores_act = cos_sim(query_embedding, emb[::2]).numpy() + ret_scores.append(np.max(cos_scores_act)) + ret_index.append(np.argmax(cos_scores_act)*2) + else: + #print('ret word obs:',actions[-1].replace('Observation: ', '')) + query_embedding = model_embedding.encode([actions[-1].replace('Observation: ', '')]) + cos_scores_act = cos_sim(query_embedding, emb[1::2]).numpy() + ret_scores.append(np.max(cos_scores_act)) + ret_index.append(np.argmax(cos_scores_act)*2+1) + else: + cos_scores_act = cos_sim(query_embedding, emb[::2]).numpy() + + ret_scores.append(np.max(cos_scores_act)) + ret_index.append(np.argmax(cos_scores_act)*2) + if config['params'].get('intra_task', False): + intra_scores.append(cos_sim(embeddings['Instruction'][a], emb[np.argmax(cos_scores_act)*2]).item()) + ret_scores = torch.FloatTensor(ret_scores) + if config['params'].get('intra_task', False): + intra_scores = torch.FloatTensor(intra_scores) + _, hits = torch.topk(ret_scores+cos_scores+intra_scores, k=k) + else: + _, hits = torch.topk(ret_scores+cos_scores, k=k) + init_prompt = '' + # ret_examples = [] + for h in hits: + part = [ + max(1, ret_index[h] - act_len + 2), + min(len(memory[h]['Actions']), ret_index[h] + act_len + 2) + ] + + retrieve_prompt = memory[h]['Actions'][0] + '\n'.join(memory[h]['Actions'][part[0]:part[1]]) + if len(init_prompt) + len(retrieve_prompt) > config['params'].get('max_init_prompt_len', 6400): + # too many retrievals, stop adding to init_prompt + break + init_prompt += '\n' + retrieve_prompt + # ret_examples.append('Task:\n' + d_log[h]['actions'][0] + '\n'.join(d_log[h]['actions'][part[0]:part[1]]) + '\n') + print(f'Retrieved from {memory[h]["Id"]}, part {part[0]} to {part[1]}') + # init_prompt = '\n'.join(ret_examples) + else: + _, hits = torch.topk(cos_scores, k=k) + ret_examples = [] + for h in hits: + ret_examples.append('\n'.join(memory[h]["Actions"])) + if len('\n'.join(ret_examples)) > config['params'].get('max_init_prompt_len', 6400): + ret_examples = ret_examples[:-1] + # too many retrievals, stop adding to init_prompt + break + print(f'Retrieved from {memory[h]["Id"]}') + init_prompt = '\n'.join(ret_examples) + return init_prompt, reasoning + +def webshop_run_react(idx, prompt, to_print=True): + action = 'reset' + init_prompt = prompt + prompt = '' + actions = [] + for i in range(1, args.num_steps+1): + try: + res = env.step(idx, action) + observation = res[0] + except AssertionError: + observation = 'Invalid action!' + + if action.startswith('think'): + observation = 'OK.' + + if to_print: + print(f'Action: {action}\nObservation: {observation}\n') + sys.stdout.flush() + if i: + prompt += f' {action}\nObservation: {observation}\n\nAction:' + # follow ReAct + actions.append(f'Action: {action}') + actions.append(f'Observation: {observation}') + else: + prompt += f'{observation}\n\nAction:' + actions.append(f'{observation}') + task = observation + + action = llm(init_prompt + prompt[-(6400-len(init_prompt)):], stop=['\n']).lstrip(' ') + + if res[2]: + # remove invalid actions and observations + inv_act_idx = np.where(np.char.find(np.array(actions), 'Invalid action!') > 0)[0] + inv_act_idx = np.append( inv_act_idx, inv_act_idx-1) + actions = [actions[i] for i in range(len(actions)) if i not in inv_act_idx] + data = { + 'Id': idx, + 'Instruction': res[3]['instruction'], + 'Actions': actions[2:-1], + 'Success': res[1] == 1, + 'Reward': res[1], + 'Category': res[3]['category'], + 'Query': res[3]['query'] + } + return res[1], data + return 0, '' + +def webshop_run_rap(idx, prompt, memory, embeddings, to_print=True): + action = 'reset' + init_prompt = prompt + prompt = '' + actions = [] + # extract examples + reasoning = '' + instruction = None + for i in range(1, args.num_steps+1): + try: + res = env.step(idx, action) + observation = res[0] + except AssertionError: + observation = 'Invalid action!' + + if action.startswith('think'): + observation = 'OK.' + + if to_print: + print(f'Action: {action}\nObservation: {observation}\n') + sys.stdout.flush() + if i: + prompt += f' {action}\nObservation: {observation}\n\nAction:' + # follow ReAct + actions.append(f'Action: {action}') + actions.append(f'Observation: {observation}') + else: + prompt += f'{observation}\n\nAction:' + actions.append(f'{observation}') + task = observation + + if instruction is None and res[3].get('instruction', None) is not None: + instruction = res[3]['instruction'].replace('Instruction: ', '') + res[3]['instruction'] = res[3]['instruction'].replace('Instruction: ', '') + elif res[3].get('instruction', None) is None: + res[3]['instruction'] = instruction.replace('Instruction: ', '') + + init_prompt, reasoning = generate_examples( + res[3], actions, memory, embeddings, reasoning, + k=config['params'].get('num_retrieval', 1), + act_len=config['params'].get('analogy_len', 0), + use_act_obs=config['params'].get('act_obs', False) + ) + full_prompt = 'Interact with a webshop application. Here are examples.\n' + init_prompt + '\nHere is the task.\n' + prompt + full_prompt = full_prompt.split('\n') + full_prompt = [f for f in full_prompt if not 'http://' in f] + full_prompt = '\n'.join(full_prompt) + full_prompt = full_prompt.replace('Observation: \nWebShop', 'WebShop') + action = llm(full_prompt, stop=['\n']).lstrip(' ') + + if res[2]: + # remove invalid actions and observations + inv_act_idx = np.where(np.char.find(np.array(actions), 'Invalid action!') > 0)[0] + inv_act_idx = np.append( inv_act_idx, inv_act_idx-1) + actions = [actions[i] for i in range(len(actions)) if i not in inv_act_idx] + data = { + 'Id': idx, + 'Instruction': res[3]['instruction'], + 'Actions': actions[2:-1], + 'Success': res[1] == 1, + 'Reward': res[1], + 'Category': res[3]['category'], + 'Query': res[3]['query'] + } + # is there a better previous memory? reflexion says not to run again, but if we run again actually we may get a better current memory + if len(memory) > 0: + prev_mem = list(filter(lambda d: d["Id"] == idx, memory)) + if len(prev_mem) > 0: + if prev_mem[0]["Success"]: + if (res[1] != 1) or (res[1] == 1 and len(prev_mem[0]["Actions"]) < len(actions[2:-1])): + data = prev_mem[0] + elif (res[1] != 1 and prev_mem[0]["Reward"] > res[1]): + data = prev_mem[0] + return res[1], data + return 0, '' + +rs_trials = [] +sr_trials = [] +for trial in range(args.num_trials): + print('### trial '+str(trial+1)+' ###') + if config['params']['split'] == 'final': + n, start = 100, 0 + elif config['params']['split'] == 'test': + n, start = 500, 0 + elif config['params']['split'] == 'eval': + n, start = 1000, 500 + else: + n, start = 10587, 1500 + + cnt = 0 + rs = [] + rs_games = [] + sr_games = [] + if trial != 0: + memory = current_memory[:] + embeddings = generate_embeddings(memory) + current_memory = [] + for i in range(start, start+n): + print('-----------------') + print(i) + if trial == 0: + try: + r, mem_data = webshop_run_react(f'fixed_{i}', initial_prompt, to_print=True) + except AssertionError: + r = 0 + cnt += 1 + mem_data = '' + + if not mem_data=='': + current_memory.append(mem_data) + else: + try: + r, mem_data = webshop_run_rap(f'fixed_{i}', initial_prompt, memory, embeddings, to_print=True) + except AssertionError: + r = 0 + cnt += 1 + mem_data = '' + + if not mem_data=='': + current_memory.append(mem_data) + + rs.append(r) + flag = r==1 + rs_games.append(r) + sr_games.append(flag) + if (i+1) % 1 == 0: + r, sr, fr = sum(rs) / len(rs), len([_ for _ in rs if _ == 1]) / len(rs), cnt / len(rs) + print(i+1, r, flag, sr, fr) + print('-------------\n') + + r, sr, fr = sum(rs) / len(rs), len([_ for _ in rs if _ == 1]) / n, cnt / n + print(r, sr, fr) + rs_trials.append(rs_games) + rs_trials_max = np.max(np.array(rs_trials), axis=0) + sr_trials.append(sr_games) + sr_trials_any = np.any(np.array(sr_trials), axis=0) + print('trial:', trial+1, 'reward score:', np.sum(rs_trials_max) / rs_trials_max.shape[0], 'success rate:', np.sum(sr_trials_any) / sr_trials_any.shape[0]) + with open(args.output+'/memory_'+str(trial+1)+'.json', 'w') as f: + json.dump(current_memory, f, indent=4) +np.savetxt(args.output+'/result_rs.txt', np.array(rs_trials).T, fmt='%.3f') +np.savetxt(args.output+'/result_sr.txt', np.array(sr_trials).T, fmt='%d') diff --git a/webshop/merged_requirements.txt b/webshop/merged_requirements.txt new file mode 100644 index 0000000..4d15033 --- /dev/null +++ b/webshop/merged_requirements.txt @@ -0,0 +1,34 @@ +--extra-index-url https://download.pytorch.org/whl/cu121 +beautifulsoup4==4.12.3 +cleantext==1.1.4 +env==0.1.0 +Flask==2.1.2 +gdown +gradio +gym==0.24.0 +numpy==1.22.4 +openai==1.30.5 +pandas==1.4.2 +pydantic==2.7.3 +pyserini==0.22.1 +pytest +PyYAML==6.0.1 +rank_bm25==0.2.2 +requests==2.32.3 +requests_mock +rich==12.4.4 +scikit_learn==1.1.1 +sentence_transformers==2.7.0 +selenium==4.2.0 +spacy==3.7.5 +thefuzz==0.19.0 +torch==2.2.2 +torchvision==0.17.2 +tqdm==4.65.0 +train==0.0.5 +transformers==4.40.1 +bitsandbytes==0.43.1 +accelerate==0.30.1 +Werkzeug==2.0.3 +faiss-gpu +python-Levenshtein diff --git a/webshop/prompts/webshop_prompt.py b/webshop/prompts/webshop_prompt.py new file mode 100644 index 0000000..20dec88 --- /dev/null +++ b/webshop/prompts/webshop_prompt.py @@ -0,0 +1,218 @@ +PROMPT1 = """Webshop +Instruction: +i would like a 3 ounce bottle of bright citrus deodorant for sensitive skin, and price lower than 50.00 dollars +[Search] + +Action: search[3 ounce bright citrus deodorant sensitive skin] +Observation: +[Back to Search] +Page 1 (Total results: 50) +[Next >] +[B078GWRC1J] +Bright Citrus Deodorant by Earth Mama | Natural and Safe for Sensitive Skin, Pregnancy and Breastfeeding, Contains Organic Calendula 3-Ounce +$10.99 +[B078GTKVXY] +Ginger Fresh Deodorant by Earth Mama | Natural and Safe for Sensitive Skin, Pregnancy and Breastfeeding, Contains Organic Calendula 3-Ounce +$10.99 +[B08KBVJ4XN] +Barrel and Oak - Aluminum-Free Deodorant, Deodorant for Men, Essential Oil-Based Scent, 24-Hour Odor Protection, Cedar & Patchouli Blend, Gentle on Sensitive Skin (Mountain Sage, 2.7 oz, 2-Pack) +$15.95 + +Action: think[B078GWRC1J and B078GTKVXY are bright citrus deodorant less then 50 dollars. I can check B078GWRC1J first.] +Observation: OK. + +Action: click[B078GWRC1J] +Observation: +[Back to Search] +[< Prev] +scent [assorted scents][bright citrus][calming lavender][ginger fresh][simply non-scents] +size [travel set (4-pack)][3 ounce (pack of 1)][3-ounce (2-pack)] +Bright Citrus Deodorant by Earth Mama | Natural and Safe for Sensitive Skin, Pregnancy and Breastfeeding, Contains Organic Calendula 3-Ounce +Price: $10.99 +Rating: N.A. +[Description] +[Features] +[Reviews] +[Buy Now] + +Action: think[For 3 ounce bottle of bright citrus deodorant for sensitive skin, the item has options 'bright citrus' and '3 ounce (pack of 1)' and seems good to buy.] +Observation: OK. + +Action: click[bright citrus] +Observation: You have clicked bright citrus. + +Action: click[3 ounce (pack of 1)] +Observation: You have clicked 3 ounce (pack of 1). + +Action: click[Buy Now] +""" + +PROMPT1_ACTONLY = """Webshop +Instruction: +i would like a 3 ounce bottle of bright citrus deodorant for sensitive skin, and price lower than 50.00 dollars +[Search] + +Action: search[3 ounce bright citrus deodorant sensitive skin] +Observation: +[Back to Search] +Page 1 (Total results: 50) +[Next >] +[B078GWRC1J] +Bright Citrus Deodorant by Earth Mama | Natural and Safe for Sensitive Skin, Pregnancy and Breastfeeding, Contains Organic Calendula 3-Ounce +$10.99 +[B078GTKVXY] +Ginger Fresh Deodorant by Earth Mama | Natural and Safe for Sensitive Skin, Pregnancy and Breastfeeding, Contains Organic Calendula 3-Ounce +$10.99 +[B08KBVJ4XN] +Barrel and Oak - Aluminum-Free Deodorant, Deodorant for Men, Essential Oil-Based Scent, 24-Hour Odor Protection, Cedar & Patchouli Blend, Gentle on Sensitive Skin (Mountain Sage, 2.7 oz, 2-Pack) +$15.95 + +Action: click[B078GWRC1J] +Observation: +[Back to Search] +[< Prev] +scent [assorted scents][bright citrus][calming lavender][ginger fresh][simply non-scents] +size [travel set (4-pack)][3 ounce (pack of 1)][3-ounce (2-pack)] +Bright Citrus Deodorant by Earth Mama | Natural and Safe for Sensitive Skin, Pregnancy and Breastfeeding, Contains Organic Calendula 3-Ounce +Price: $10.99 +Rating: N.A. +[Description] +[Features] +[Reviews] +[Buy Now] + +Action: click[bright citrus] +Observation: You have clicked bright citrus. + +Action: click[3 ounce (pack of 1)] +Observation: You have clicked 3 ounce (pack of 1). + +Action: click[Buy Now] +""" + +PROMPT1_V2 = """Webshop +Instruction: +i would like a 3 ounce bottle of bright citrus deodorant for sensitive skin, and price lower than 50.00 dollars +[Search] + +Action: search[3 ounce bright citrus deodorant sensitive skin] +Observation: +[Back to Search] +Page 1 (Total results: 50) +[Next >] +[B078GWRC1J] +Bright Citrus Deodorant by Earth Mama | Natural and Safe for Sensitive Skin, Pregnancy and Breastfeeding, Contains Organic Calendula 3-Ounce +$10.99 +[B078GTKVXY] +Ginger Fresh Deodorant by Earth Mama | Natural and Safe for Sensitive Skin, Pregnancy and Breastfeeding, Contains Organic Calendula 3-Ounce +$10.99 +[B08KBVJ4XN] +Barrel and Oak - Aluminum-Free Deodorant, Deodorant for Men, Essential Oil-Based Scent, 24-Hour Odor Protection, Cedar & Patchouli Blend, Gentle on Sensitive Skin (Mountain Sage, 2.7 oz, 2-Pack) +$15.95 + +Action: think[I see 3 products: B078GWRC1J, B078GTKVXY and B08KBVJ4XN. If these products do not match my task of bright citrus deodorant less then 50 dollars, I can then click[Back to Search] and search again.] +Observation: OK. + +Action: think[078GWRC1J and B078GTKVXY are bright citrus deodorant less then 50 dollars. I can check B078GWRC1J first. If this does not match my criteria, I can then click[< Prev] and check B078GTKVXY.] +Observation: OK. + +Action: click[B078GWRC1J] +Observation: +[Back to Search] +[< Prev] +scent [assorted scents][bright citrus][calming lavender][ginger fresh][simply non-scents] +size [travel set (4-pack)][3 ounce (pack of 1)][3-ounce (2-pack)] +Bright Citrus Deodorant by Earth Mama | Natural and Safe for Sensitive Skin, Pregnancy and Breastfeeding, Contains Organic Calendula 3-Ounce +Price: $10.99 +Rating: N.A. +[Description] +[Features] +[Reviews] +[Attributes] +[Buy Now] + +Action: think[I am at the product item page for B078GWRC1J. If I click on any of the buttons [Description], [Features], [Reviews] or [Attributes], I have to click[< Prev] before I can click[Buy Now].] +Observation: OK. + +Action: think[This item has option types scent and size. The scent type has options 'assorted scents', 'bright citrus', 'calming lavender', 'ginger fresh' and 'simply non-scents'. The size type has options 'travel set (4-pack)', '3 ounce (pack of 1)' and '3-ounce (2-pack)'.] +Observation: OK. + +Action: think[For 3 ounce bottle of bright citrus deodorant for sensitive skin, the item has options 'bright citrus' and '3 ounce (pack of 1)' and seems good to buy.] +Observation: OK. + +Action: click[bright citrus] +Observation: You have clicked bright citrus. + +Action: click[3 ounce (pack of 1)] +Observation: You have clicked 3 ounce (pack of 1). + +Action: click[Buy Now] +""" + + +PROMPT1_V3 = """Webshop +Instruction: +i would like a 3 ounce bottle of bright citrus deodorant for sensitive skin, and price lower than 50.00 dollars +[Search] + +Action: search[3 ounce bright citrus deodorant sensitive skin] +Observation: +[Back to Search] +Page 1 (Total results: 50) +[Next >] +[B078GWRC1J] +Bright Citrus Deodorant by Earth Mama | Natural and Safe for Sensitive Skin, Pregnancy and Breastfeeding, Contains Organic Calendula 3-Ounce +$10.99 +[B078GTKVXY] +Ginger Fresh Deodorant by Earth Mama | Natural and Safe for Sensitive Skin, Pregnancy and Breastfeeding, Contains Organic Calendula 3-Ounce +$10.99 +[B08KBVJ4XN] +Barrel and Oak - Aluminum-Free Deodorant, Deodorant for Men, Essential Oil-Based Scent, 24-Hour Odor Protection, Cedar & Patchouli Blend, Gentle on Sensitive Skin (Mountain Sage, 2.7 oz, 2-Pack) +$15.95 + +Action: think[I see 3 products: B078GWRC1J, B078GTKVXY and B08KBVJ4XN. If these products do not match my task of bright citrus deodorant less then 50 dollars, I can then click[Back to Search] and search again.] +Observation: OK. + +Action: think[B078GWRC1J and B078GTKVXY are bright citrus deodorant less then 50 dollars. I can check B078GWRC1J first. Only if this item does not fit my criteria, I can then click[< Prev] and check B078GTKVXY.] +Observation: OK. + +Action: click[B078GWRC1J] +Observation: +[Back to Search] +[< Prev] +scent [assorted scents][bright citrus][calming lavender][ginger fresh][simply non-scents] +size [travel set (4-pack)][3 ounce (pack of 1)][3-ounce (2-pack)] +Bright Citrus Deodorant by Earth Mama | Natural and Safe for Sensitive Skin, Pregnancy and Breastfeeding, Contains Organic Calendula 3-Ounce +Price: $10.99 +Rating: N.A. +[Description] +[Features] +[Reviews] +[Attributes] +[Buy Now] + +Action: think[I am at the product item page for B078GWRC1J. If I click on any of the buttons [Description], [Features], [Reviews] or [Attributes], I have to click[< Prev] before I can click[Buy Now].] +Observation: OK. + +Action: think[For 3 ounce bottle of bright citrus deodorant for sensitive skin, the item has options 'bright citrus' and '3 ounce (pack of 1)' and seems good to buy.] +Observation: OK. + +Action: click[bright citrus] +Observation: You have clicked bright citrus. + +Action: click[3 ounce (pack of 1)] +Observation: You have clicked 3 ounce (pack of 1). + +Action: think[I have selected 'bright citrus' and '3 ounce (pack of 1)', and this item is 10.99 dollars. This matches my criteria of 3 ounce bright citrus deodorant sensitive skin less than 50 dollars. I can click on the [Buy Now] button.] +Observation: OK. + +Action: click[Buy Now] +""" + + +INITIAL_PROMPTS = { + "PROMPT1": PROMPT1, + "PROMPT1_ACTONLY": PROMPT1_ACTONLY, + "PROMPT1_V2": PROMPT1_V2, + "PROMPT1_V3": PROMPT1_V3 +} \ No newline at end of file diff --git a/webshop/requirements.txt b/webshop/requirements.txt new file mode 100644 index 0000000..32dd797 --- /dev/null +++ b/webshop/requirements.txt @@ -0,0 +1,11 @@ +--extra-index-url https://download.pytorch.org/whl/cu121 +beautifulsoup4==4.12.3 +numpy==1.22.4 +openai==1.30.5 +PyYAML==6.0.1 +Requests==2.32.3 +sentence_transformers==2.7.0 +torch==2.2.2 +transformers==4.40.1 +bitsandbytes==0.43.1 +accelerate==0.30.1