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).
+
+
+
+# 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