[
  {
    "path": ".github/ISSUE_TEMPLATE/001-report-bug.yml",
    "content": "name: Bug report\ndescription: Raise an issue here if you find a bug.\ntitle: \"[Bug] \"\nlabels: [\"bug\"]\n\nbody:\n- type: checkboxes\n  attributes:\n    label: Checked other resources\n    description: Please confirm and check all the following options.\n    options:\n    - label: I added a very descriptive title to this issue.\n      required: true\n    - label: I am sure the issue hasn't been already addressed by searching through https://github.com/agiresearch/OpenAGI/issues.\n      required: true\n    - label: The usage issue is not resolved by updating to the latest stable version in the main branch.\n      required: true\n  validations:\n    required: true\n- type: textarea\n  attributes:\n    label: Describe your current environment\n    description: |\n      Your current environment information (including OS, GPU, Cuda-version)\n- type: textarea\n  attributes:\n    label: Describe the bug\n    description: |\n      Please provide a clear and concise description of what the bug is.\n      If relevant, add a minimal example so that we can reproduce the error by running the code.\n  validations:\n    required: true\n- type: markdown\n  attributes:\n    value: >\n      Thanks for contributing 🎉!\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/002-feature-request.yml",
    "content": "name: Feature request\ndescription: Submit a proposal/request for a new aios feature\ntitle: \"[Feature] \"\nlabels: [\"feature request\"]\n\nbody:\n- type: checkboxes\n  attributes:\n    label: Checked other resources\n    description: Please confirm and check all the following options.\n    options:\n      - label: I added a very descriptive title to this issue.\n        required: true\n      - label: I am sure the issue hasn't been already addressed by searching through https://github.com/agiresearch/OpenAGI/issues.\n        required: true\n- type: textarea\n  attributes:\n    label: The feature, motivation and pitch\n    description: >\n      A clear and concise description of the feature proposal. Please outline the motivation for the proposal. Is your feature request related to a specific problem? e.g., *\"I'm working on X and would like Y to be possible\"*. If this is related to another GitHub issue, please link here too.\n  validations:\n    required: true\n- type: textarea\n  attributes:\n    label: Alternatives\n    description: >\n      A description of any alternative solutions or features you've considered, if any.\n- type: textarea\n  attributes:\n    label: Additional context\n    description: >\n      Add any other context or screenshots about the feature request.\n- type: markdown\n  attributes:\n    value: >\n      Thanks for contributing 🎉!\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/003-misc-discussion.yml",
    "content": "name: Misc/random discussions that do not fit into the above categories.\ndescription: Submit a discussion as you like. Note that developers are heavily overloaded and we mainly rely on community users to answer these issues.\ntitle: \"[Misc] \"\nlabels: [\"misc discussion\"]\n\nbody:\n- type: textarea\n  attributes:\n    label: Anything you want to discuss about aios.\n    description: >\n      Anything you want to discuss about aios.\n  validations:\n    required: true\n- type: markdown\n  attributes:\n    value: >\n      Thanks for contributing 🎉!\n"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "content": "Thank you for your contribution to OpenAGI!\nBefore submitting the pull request, please ensure **the PR meets the following criteria**! This helps improve the efficiency of the review process.\n\n### Code Quality\nBefore submitting your PR, you need to follow the steps below to maintain code quality.\n- Use `pip install -r requirements-dev.txt` to install the extra dependencies in requirements-dev.txt for the following checks.\n- Use `pre-commit install` to install pre-commit locally before you commit messages. The pre-commit can help correct the style that are added or modified.\n- Use `pytest -v tests/` to run the test code and make sure it passes all the checks.\n\n### PR title and classification\nOnly specific types of PRs will be reviewed. The PR title is prefixed appropriately (i.e., \"prefix: description\") to indicate the type of change. Please use one of the prefixs as below:\n- `feat` Add new features\n- `fix`  Fix bugs\n- `docs` Modify documents like README, CONTRIBUTE\n- `style` Modify code format like space and comma without changing code logic\n- `refactor` Refactor code structure without adding new features or fixing new bugs\n- `perf` Improve performance or user experience\n- `test` Test features, including unit test and integration test\n- `chore` Change the build procedure or add dependencies\n- `revert` Revert to the previous version\n\n### PR messages\n- **Description:** a description of the change\n- **Issue:** the issue # it fixes, if applicable\n- **Dependencies:** any dependencies required for this change\n\n### For the Reviews\n- After the PR is submitted, the PR will be assigned to a reviewer. Every reviewer will pick up the PRs based on their expertise and availability.\n- If no one reviews your PR within a few days, please @-mention one of [dongyuanjushi](https://github.com/dongyuanjushi/), [evison](https://github.com/evison), [Wenyueh](https://github.com/Wenyueh), [BRama10](https://github.com/BRama10).\n"
  },
  {
    "path": ".github/workflows/ci.yml",
    "content": "name: CI\n\non:\n  [push,pull_request]\n\njobs:\n  run-pytest:\n    runs-on: ubuntu-latest\n\n    steps:\n    - uses: actions/checkout@v2\n\n    - name: Set up Python\n      uses: actions/setup-python@v2\n      with:\n        python-version: \"3.11\"\n\n    - name: Install dependencies\n      run: |\n        python -m pip install --upgrade pip\n        pip install -r requirements-dev.txt\n\n    - name: Run tests\n      run: |\n        pytest -v tests\n"
  },
  {
    "path": ".github/workflows/publish.yml",
    "content": "name: Publish Python Package\n\non:\n  push:\n    tags:\n      - \"v*\"\n\njobs:\n  deploy:\n    runs-on: ubuntu-latest\n\n    environment: release\n    permissions:\n      id-token: write\n\n    steps:\n      - uses: actions/checkout@v4\n      - name: Set up Python\n        uses: actions/setup-python@v4\n        with:\n          python-version: \"3.11\"\n          cache: \"pip\"\n      - name: Install dependencies\n        run: |\n          python -m pip install --upgrade pip\n          pip install hatch\n      - name: Build package\n        run: hatch build\n      - name: Publish package distributions to PyPI\n        uses: pypa/gh-action-pypi-publish@release/v1\n"
  },
  {
    "path": ".gitignore",
    "content": ".idea/\n.vscode/\n\n.DS_Store\n\n# Ignore Python compiled files\n__pycache__/\n*.py[cod]\n\n# Ignore Mac system files\n.DS_Store\n\n# Ignore package info\n*.egg-info/\n\n\n*.ipynb\n\napi_key.py\n\ngenerated_images/\n\ngenerated_poems/\n\ngenerated_music/\n\n./UI/.env*.local\n.env\n\nchroma_db/\n\ndist/\n/dist/\ndist"
  },
  {
    "path": ".pre-commit-config.yaml",
    "content": "repos:\n-   repo: https://github.com/pre-commit/pre-commit-hooks\n    rev: v3.2.0\n    hooks:\n    -   id: trailing-whitespace\n    -   id: end-of-file-fixer\n    -   id: check-yaml\n    -   id: check-added-large-files\n"
  },
  {
    "path": "CONTRIBUTE.md",
    "content": "# How to contribute to OpenAGI\nThank you for your interest in OpenAGI!\nHere's a guide to help you contribute to this project.\n\n## 1. Get Started\n### Fork the repository\n\nAt first, you need to fork this copy and create your own version of repo.\n\n### Clone the repository and install the dependencies.\n\n### Installing dependencies with pip\n```bash\npip install -r requirements.txt\n```\n\n### Installing pre-commit\nWe strongly recommend installing [pre-commit](https://pre-commit.com/) to ensure proper formatting during development\n\n## 2. Developing and Testing\n### Create a branch\n\nCreate a new branch for developing your creative features\n\n```shell\ngit checkout -b your-feature\n```\n\n### Make changes and testing\n\nYou can develop new features and then you need to make sure everything works as expected. Run our provided tests and make sure the existing ones go well. Your new tests are encouraged.\n\n### Run tests\n\nAdd your test code into the `openagi/tests/` directory if any, then run test via [pytest](https://docs.pytest.org/en/8.0.x/)\n\n```\ncd openagi\npytest -v tests\n```\nsample output\n```\n============================================================================================================================= test session starts ==============================================================================================================================\nplatform darwin -- Python 3.11.9, pytest-8.1.1, pluggy-1.5.0 -- \"\"\ncachedir: .pytest_cache\nrootdir: \"\"\nplugins: anyio-4.3.0\ncollected 2 items\n\ntests/test_agent_creation.py::test_agent_creation PASSED                                                                                                                                                                                                                 [ 50%]\ntests/test_tools.py::test_currency_converter_api PASSED                                                                                                                                                                                                                  [100%]\n```\n\n## 3. Submitting Changes\n\n### Code format check\nPlease ensure your code is formatted correctly using pre-commit\n\n### Git commit message\nWe strongly recommend your git commit follows the format below\n```bash\ngit commit -m <type>: <subject>\n```\n\n| <type> | <subject>                                     |\n|-------------|--------------------------------------------------|\n| `feat`      | Add new features                                 |\n| `fix`       | Fix bugs                                         |\n| `docs`      | Modify documents like README, CONTRIBUTE         |\n| `style`     | Modify code format like space and comma without changing code logic |\n| `refactor`  | Refactor code structure without adding new features or fixing new bugs |\n| `perf`      | Improve performance or user experience                              |\n| `test`      | Test features, including unit test and integration test |\n| `chore`     | Change the build procedure or add dependencies   |\n| `revert`    | Revert to the previous version                   |\n\n💡Try to shrink the number of git commit messages to make it clear and concise. If you find you have already made too many commit messages, no worries, use git rebase and squash to merge multiple messages. Here is the [guide](https://www.freecodecamp.org/news/git-squash-commits/#:~:text=The%20first%20thing%20you%20need,to%20go%20back%206%20commits.&text=Now%2C%20you%20need%20to%20replace,apart%20from%20the%20first%20one).\n### Create a Pull Request\n\n1. Visit your forked AIOS repository on GitHub and click the \"Compare & pull request\" button to initiate the process of submitting your changes to the original repository for review and potential merging.\n2. Choose the base branch and the compare branch (your feature branch).💡 Note that when you add new features, it is recommended to choose the (`dev`) branch and if your change does not affect original functions, you may consider choosing the (`main`) branch.\n3. Write a title and describe your changes in the description. And it is recommended to select the label of the change to make it more clear.\n\n## 4. Review and Approval\nOur maintainers will have a review of that and might give some suggestions or ask for more details. After they approve, your commitment can be incorporated into OpenAGI!\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2024 AGI Research\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# OpenAGI: Package for AI Agent Creation\n<a href='https://arxiv.org/abs/2304.04370'><img src='https://img.shields.io/badge/Paper-PDF-red'></a>\n[![Code License](https://img.shields.io/badge/Code%20License-MIT-green.svg)](https://github.com/agiresearch/OpenAGI/blob/main/LICENSE)\n<a href='https://discord.gg/B2HFxEgTJX'><img src='https://img.shields.io/badge/Community-Discord-8A2BE2'></a>\n\n\n## ✈️ Getting Started\nOpenAGI is used as the agent creation package to build agents for [AIOS](https://github.com/agiresearch/AIOS).\n**Notice:** For building up agents in the AIOS, please migrate to the [Cerebrum](https://github.com/agiresearch/Cerebrum), which is our latest SDK to connect with AIOS kernel.\n\n### Installation\nFrom PyPI\n```\npip install pyopenagi\n```\nLocally\n```\ngit clone https://agiresearch/OpenAGI\ncd OpenAGI\npip install -e .\n```\n\n### Usage\n\n#### Add a new agent\nTo add a new agent, first you need to create a folder under the pyopenagi/agents folder.\nThe folder needs to be the following structure:\n```\n- pyopenagi/agents\n  - author\n    - agent_name\n      - agent.py # main code for the agent execution logic\n      - config.json # set up configurations for agent\n      - meta_requirements.txt # dependencies that the agent needs\n```\nIf you want to use external tools provided by openagi in your agents, you can follow instructions of setting up tools in [How to setup external tools](./tools.md).\nIf you want to add new tools for your developing agent,\nyou need to add a new tool file in the [folder](./pyopenagi/tools/).\n\n#### Upload agent\nIf you have developed and tested your agent, and you would like to share your agents, you can use the following to upload your agents\n```\npython pyopenagi/agents/interact.py --mode upload --agent <author_name/agent_name>\n```\n💡Note that the `agent` param must exactly match the folder you put your agent locally.\n\n#### Download agent\nIf you want to look at implementations of other agents that others have developed, you can use the following command:\n```\npython pyopenagi/agents/interact.py --mode download --agent <author_name/agent_name>\n```\n\n## 🚀 Contributions\n\nFor detailed information on how to contribute, see [CONTRIBUTE](./CONTRIBUTE.md). If you would like to contribute to the codebase, [issues](https://github.com/agiresearch/OpenAGI/issues) or [pull requests](https://github.com/agiresearch/OpenAGI/pulls) are always welcome!\n\n## 🖋️ Research\nPlease check out our [implementation](https://github.com/agiresearch/OpenAGI/tree/research) for our research paper [OpenAGI: When LLM Meets Domain Experts](https://arxiv.org/abs/2304.04370).\n\n```\n@article{openagi,\n  title={OpenAGI: When LLM Meets Domain Experts},\n  author={Ge, Yingqiang and Hua, Wenyue and Mei, Kai and Ji, Jianchao and Tan, Juntao and Xu, Shuyuan and Li, Zelong and Zhang, Yongfeng},\n  journal={In Advances in Neural Information Processing Systems (NeurIPS)},\n  year={2023}\n}\n```\n\n## 🌍 OpenAGI Contributors\n[![OpenAGI contributors](https://contrib.rocks/image?repo=agiresearch/OpenAGI&max=300)](https://github.com/agiresearch/OpenAGI/graphs/contributors)\n\n\n\n## 🌟 Star History\n\n[![Star History Chart](https://api.star-history.com/svg?repos=agiresearch/OpenAGI&type=Date)](https://star-history.com/#agiresearch/OpenAGI&Date)\n"
  },
  {
    "path": "pyopenagi/README.md",
    "content": "# pyopenagi\n\nThe internal implementation for OpenAGI.\n\n1. `agents/` contains the agent implementation all future agents have to follow.\n2. `queues/` contains the class implementation for queues.\n3. `utils/` contains some helpful internal utilities.\n4. `tools/` contains the tools the agents can use.\n"
  },
  {
    "path": "pyopenagi/__init__.py",
    "content": ""
  },
  {
    "path": "pyopenagi/agents/README.md",
    "content": "# pyopenagi/agents\nThis folder contains the base implementation for running the agents, as well as the handlers for running multiple agents in Threads in `agent_process.py` and `agent_factory.py`\n\nIn `example/` we have some example agents. You can add agents to that directory or to `your-cool-identifier/` to show your agent off in the main repo. However, it is recommended to use the agent database over submitting a pull request, unless it is for demo purposes.\n"
  },
  {
    "path": "pyopenagi/agents/__init__.py",
    "content": ""
  },
  {
    "path": "pyopenagi/agents/agent_factory.py",
    "content": "from threading import Lock\nfrom pympler import asizeof\nfrom .interact import Interactor\nimport os\nimport importlib\nimport random\nclass AgentFactory:\n    def __init__(self,\n                #  agent_process_queue,\n                 agent_process_factory,\n                 agent_log_mode\n        ):\n        # self.max_aid = 256\n        # self.llm = llm\n        # self.aid_pool = [i for i in range(self.max_aid)]\n        # heapq.heapify(self.aid_pool)\n        # self.agent_process_queue = agent_process_queue\n        self.agent_process_factory = agent_process_factory\n\n        self.current_agents = {}\n\n        self.current_agents_lock = Lock()\n\n        # self.terminate_signal = Event()\n\n        self.agent_log_mode = agent_log_mode\n\n    def snake_to_camel(self, snake_str):\n        components = snake_str.split('_')\n        return ''.join(x.title() for x in components)\n\n    def list_agents(self):\n        agent_list = Interactor().list_available_agents()\n        for agent in agent_list:\n            print(agent)\n\n    def load_agent_instance(self, agent_name):\n        # dynamically loads the module from the path\n        author, name = agent_name.split(\"/\")\n        module_name = \".\".join([\"pyopenagi\", \"agents\", author, name, \"agent\"])\n        class_name = self.snake_to_camel(name)\n\n        agent_module = importlib.import_module(module_name)\n\n        # dynamically loads the class\n        agent_class = getattr(agent_module, class_name)\n        \n        return agent_class\n\n    def activate_agent(self, agent_name, task_input):\n        script_path = os.path.abspath(__file__)\n        script_dir = os.path.dirname(script_path)\n\n        # downloads the agent if its not installed already\n        interactor = Interactor()\n\n        if not os.path.exists(os.path.join(script_dir, agent_name)):\n            interactor.download_agent(agent_name)\n\n        if not interactor.check_reqs_installed(agent_name):\n            interactor.install_agent_reqs(agent_name)\n\n        # we instantiate the agent directly from the class\n        agent_class = self.load_agent_instance(agent_name)\n\n        agent = agent_class(\n            agent_name = agent_name,\n            task_input = task_input,\n            agent_process_factory = self.agent_process_factory,\n            log_mode = self.agent_log_mode\n        )\n\n        aid = random.randint(100000, 999999)\n        # set the identifier for the agent\n        # aid = heapq.heappop(self.aid_pool)\n        agent.set_aid(aid)\n\n        # use a lock to make sure only one agent can read the values at a time\n        # if not self.terminate_signal.is_set():\n        with self.current_agents_lock:\n            self.current_agents[aid] = agent\n\n        return agent\n\n    def run_agent(self, agent_name, task_input):\n        agent = self.activate_agent(\n            agent_name=agent_name,\n            task_input=task_input\n        )\n        # print(task_input)\n        output = agent.run()\n        self.deactivate_agent(agent.get_aid())\n        return output\n\n    def print_agent(self):\n        headers = [\"Agent ID\", \"Agent Name\", \"Created Time\", \"Status\", \"Memory Usage\"]\n        data = []\n        for id, agent in self.current_agents.items():\n            agent_name = agent.agent_name\n            created_time = agent.created_time\n            status = agent.status\n            memory_usage = f\"{asizeof.asizeof(agent)} bytes\"\n            data.append(\n                [id, agent_name, created_time, status, memory_usage]\n            )\n        self.print(headers=headers, data=data)\n\n\n    def print(self, headers, data):\n        # align output\n        column_widths = [\n            max(len(str(row[i])) for row in [headers] + data) for i in range(len(headers))\n        ]\n        print(\"+\" + \"-\" * (sum(column_widths) + len(headers) * 3 - 3 ) + \"+\")\n        print(self.format_row(headers, column_widths))\n        print(\"=\" * (sum(column_widths) + len(headers) * 3 - 1))\n        for i, row in enumerate(data):\n            print(self.format_row(row, column_widths))\n            if i < len(data):\n                print(\"-\" * (sum(column_widths) + len(headers) * 3 - 1))\n        print(\"+\" + \"-\" * (sum(column_widths) + len(headers) * 3 - 3 ) + \"+\")\n\n\n    def format_row(self, row, widths, align=\"<\"):\n        row_str = \" | \".join(f\"{str(item):{align}{widths[i]}}\" for i, item in enumerate(row))\n        return row_str\n\n    def deactivate_agent(self, aid):\n        self.current_agents.pop(aid)\n        # heapq.heappush(self.aid_pool, aid)\n"
  },
  {
    "path": "pyopenagi/agents/agent_process.py",
    "content": "from threading import Thread, Lock\n\nfrom ..utils.chat_template import Query\nimport random\nclass AgentProcess:\n    def __init__(self,\n            agent_name: str,\n            query: Query\n        ):\n        \"\"\"Agent Process\n\n        Args:\n            agent_name (str): Name of the agent\n            query (Query): Query sent by the agent\n        \"\"\"\n        self.agent_name = agent_name\n        self.query = query\n        self.pid: int = None\n        self.status = None\n        self.response = None\n        self.time_limit = None\n        self.created_time = None\n        self.start_time = None\n        self.end_time = None\n\n    def set_created_time(self, time):\n        self.created_time = time\n\n    def get_created_time(self):\n        return self.created_time\n\n    def set_start_time(self, time):\n        self.start_time = time\n\n    def get_start_time(self):\n        return self.start_time\n\n    def set_end_time(self, time):\n        self.end_time = time\n\n    def get_end_time(self):\n        return self.end_time\n\n    def set_priority(self, priority):\n        self.priority = priority\n\n    def get_priority(self):\n        return self.priority\n\n    def set_status(self, status):\n        self.status = status\n\n    def get_status(self):\n        return self.status\n\n    def set_pid(self, pid):\n        self.pid = pid\n\n    def get_pid(self):\n        return self.pid\n\n    def get_response(self):\n        return self.response\n\n    def set_response(self, response):\n        self.response = response\n\n    def get_time_limit(self):\n        return self.time_limit\n\n    def set_time_limit(self, time_limit):\n        self.time_limit = time_limit\n\n\nclass LLMRequestProcess(AgentProcess):\n    pass\n\nclass AgentProcessFactory:\n    def __init__(self, agent_process_log_mode = None):\n        # self.max_pid = 1024\n        # self.pid_pool = [i for i in range(self.max_pid)]\n        # heapq.heapify(self.pid_pool)\n\n        self.thread = Thread(target=self.deactivate_agent_process)\n\n        self.current_agent_processes = dict()\n\n        self.current_agent_processes_lock = Lock()\n\n        # self.terminate_signal = Event()\n\n        self.agent_process_log_mode = agent_process_log_mode\n\n    def activate_agent_process(self, agent_name, query):\n        # if not self.terminate_signal.is_set():\n        with self.current_agent_processes_lock:\n            agent_process = AgentProcess(\n                agent_name = agent_name,\n                query = query\n            )\n            pid = random.randint(1000000, 9999999)\n            # pid = heapq.heappop(self.pid_pool)\n            agent_process.set_pid(pid)\n            agent_process.set_status(\"active\")\n            self.current_agent_processes[pid] = agent_process\n            return agent_process\n\n    def print_agent_process(self):\n        headers = [\"Agent Process ID\", \"Agent Name\", \"Created Time\", \"Status\"]\n        data = []\n        for id, agent_process in self.current_agent_processes.items():\n            agent_name = agent_process.agent_name\n            created_time = agent_process.created_time\n            status = agent_process.status\n            # memory_usage = f\"{asizeof.asizeof(agent)} bytes\"\n            data.append(\n                [id, agent_name, created_time, status]\n            )\n        self.print(headers=headers, data=data)\n\n\n    def print(self, headers, data):\n        # align output\n        column_widths = [\n            max(len(str(row[i])) for row in [headers] + data) for i in range(len(headers))\n        ]\n        print(\"+\" + \"-\" * (sum(column_widths) + len(headers) * 3 - 3 ) + \"+\")\n        print(self.format_row(headers, column_widths))\n        print(\"=\" * (sum(column_widths) + len(headers) * 3 - 1))\n        for i, row in enumerate(data):\n            print(self.format_row(row, column_widths))\n            if i < len(data):\n                print(\"-\" * (sum(column_widths) + len(headers) * 3 - 1))\n        print(\"+\" + \"-\" * (sum(column_widths) + len(headers) * 3 - 3 ) + \"+\")\n\n\n    def format_row(self, row, widths, align=\"<\"):\n        row_str = \" | \".join(f\"{str(item):{align}{widths[i]}}\" for i, item in enumerate(row))\n        return row_str\n\n    def deactivate_agent_process(self, pid):\n        self.current_agent_processes.pop(pid)\n        # heapq.heappush(self.pid_pool, pid)\n\n    def start(self):\n        \"\"\"start the factory to check inactive agent\"\"\"\n        self.thread.start()\n\n    def stop(self):\n        self.thread.join()\n"
  },
  {
    "path": "pyopenagi/agents/base_agent.py",
    "content": "import os\n\nimport json\n\nfrom .agent_process import (\n    AgentProcess\n)\n\nimport time\n\nfrom threading import Thread\n\nfrom ..utils.logger import AgentLogger\n\nfrom ..utils.chat_template import Query\n\nimport importlib\n\nfrom aios.hooks.stores._global import global_llm_req_queue_add_message\n\nclass CustomizedThread(Thread):\n    def __init__(self, target, args=()):\n        super().__init__()\n        self.target = target\n        self.args = args\n        self.result = None\n\n    def run(self):\n        self.result = self.target(*self.args)\n\n    def join(self):\n        super().join()\n        return self.result\n\nclass BaseAgent:\n    def __init__(self,\n                 agent_name,\n                 task_input,\n                 agent_process_factory,\n                 log_mode: str\n        ):\n\n        self.agent_name = agent_name\n        self.config = self.load_config()\n        self.tool_names = self.config[\"tools\"]\n\n        self.agent_process_factory = agent_process_factory\n\n        self.tool_list = dict()\n        self.tools = []\n        self.tool_info = [] # simplified information of the tool: {\"name\": \"xxx\", \"description\": \"xxx\"}\n\n        self.load_tools(self.tool_names)\n\n        self.start_time = None\n        self.end_time = None\n        self.request_waiting_times: list = []\n        self.request_turnaround_times: list = []\n        self.task_input = task_input\n        self.messages = []\n        self.workflow_mode = \"manual\" # (mannual, automatic)\n        self.rounds = 0\n\n        self.log_mode = log_mode\n        self.logger = self.setup_logger()\n        self.logger.log(\"Initialized. \\n\", level=\"info\")\n\n        self.set_status(\"active\")\n        self.set_created_time(time.time())\n\n\n    def run(self):\n        '''Execute each step to finish the task.'''\n        pass\n\n    # can be customization\n    def build_system_instruction(self):\n        pass\n\n    def check_workflow(self, message):\n        try:\n            # print(f\"Workflow message: {message}\")\n            workflow = json.loads(message)\n            if not isinstance(workflow, list):\n                return None\n\n            for step in workflow:\n                if \"message\" not in step or \"tool_use\" not in step:\n                    return None\n\n            return workflow\n\n        except json.JSONDecodeError:\n            return None\n\n    def automatic_workflow(self):\n        for i in range(self.plan_max_fail_times):\n            response, start_times, end_times, waiting_times, turnaround_times = self.get_response(\n                query = Query(\n                    messages = self.messages,\n                    tools = None,\n                    message_return_type=\"json\"\n                )\n            )\n\n            if self.rounds == 0:\n                self.set_start_time(start_times[0])\n\n            self.request_waiting_times.extend(waiting_times)\n            self.request_turnaround_times.extend(turnaround_times)\n\n            workflow = self.check_workflow(response.response_message)\n\n            self.rounds += 1\n\n            if workflow:\n                return workflow\n\n            else:\n                self.messages.append(\n                    {\n                        \"role\": \"assistant\",\n                        \"content\": f\"Fail {i+1} times to generate a valid plan. I need to regenerate a plan\"\n                    }\n                )\n        return None\n\n    def manual_workflow(self):\n        pass\n\n    def check_path(self, tool_calls):\n        script_path = os.path.abspath(__file__)\n        save_dir = os.path.join(os.path.dirname(script_path), \"output\") # modify the customized output path for saving outputs\n        if not os.path.exists(save_dir):\n            os.makedirs(save_dir)\n        for tool_call in tool_calls:\n            try:\n                for k in tool_call[\"parameters\"]:\n                    if \"path\" in k:\n                        path = tool_call[\"parameters\"][k]\n                        if not path.startswith(save_dir):\n                            tool_call[\"parameters\"][k] = os.path.join(save_dir, os.path.basename(path))\n            except Exception:\n                continue\n        return tool_calls\n\n    def snake_to_camel(self, snake_str):\n        components = snake_str.split('_')\n        return ''.join(x.title() for x in components)\n\n    def load_tools(self, tool_names):\n\n        for tool_name in tool_names:\n            org, name = tool_name.split(\"/\")\n            module_name = \".\".join([\"pyopenagi\", \"tools\", org, name])\n            class_name = self.snake_to_camel(name)\n            tool_module = importlib.import_module(module_name)\n            tool_class = getattr(tool_module, class_name)\n            self.tool_list[name] = tool_class()\n            tool_format = tool_class().get_tool_call_format()\n            self.tools.append(tool_format)\n            self.tool_info.append(\n                {\"name\": tool_format[\"function\"][\"name\"], \"description\": tool_format[\"function\"][\"description\"]}\n            )\n\n    def pre_select_tools(self, tool_names):\n        pre_selected_tools = []\n        for tool_name in tool_names:\n            for tool in self.tools:\n                if tool[\"function\"][\"name\"] == tool_name:\n                    pre_selected_tools.append(tool)\n                    break\n\n        return pre_selected_tools\n\n    def setup_logger(self):\n        logger = AgentLogger(self.agent_name, self.log_mode)\n        return logger\n\n    def load_config(self):\n        script_path = os.path.abspath(__file__)\n        script_dir = os.path.dirname(script_path)\n        config_file = os.path.join(script_dir, self.agent_name, \"config.json\")\n        with open(config_file, \"r\") as f:\n            config = json.load(f)\n            return config\n\n    # the default method used for getting response from AIOS\n    def get_response(self,\n            query,\n            temperature=0.0\n        ):\n\n        thread = CustomizedThread(target=self.query_loop, args=(query, ))\n        thread.start()\n        return thread.join()\n\n    def query_loop(self, query):\n        agent_process = self.create_agent_request(query)\n\n        completed_response, start_times, end_times, waiting_times, turnaround_times = \"\", [], [], [], []\n\n        while agent_process.get_status() != \"done\":\n            thread = Thread(target=self.listen, args=(agent_process, ))\n            current_time = time.time()\n            # reinitialize agent status\n            agent_process.set_created_time(current_time)\n            agent_process.set_response(None)\n\n            global_llm_req_queue_add_message(agent_process)\n\n            # LLMRequestQueue.add_message(agent_process)\n\n            thread.start()\n            thread.join()\n\n            completed_response = agent_process.get_response()\n            if agent_process.get_status() != \"done\":\n                self.logger.log(\n                    f\"Suspended due to the reach of time limit ({agent_process.get_time_limit()}s). Current result is: {completed_response.response_message}\\n\",\n                    level=\"suspending\"\n                )\n            start_time = agent_process.get_start_time()\n            end_time = agent_process.get_end_time()\n            waiting_time = start_time - agent_process.get_created_time()\n            turnaround_time = end_time - agent_process.get_created_time()\n\n            start_times.append(start_time)\n            end_times.append(end_time)\n            waiting_times.append(waiting_time)\n            turnaround_times.append(turnaround_time)\n            # Re-start the thread if not done\n\n        # self.agent_process_factory.deactivate_agent_process(agent_process.get_pid())\n\n        return completed_response, start_times, end_times, waiting_times, turnaround_times\n\n    def create_agent_request(self, query):\n        agent_process = self.agent_process_factory.activate_agent_process(\n            agent_name = self.agent_name,\n            query = query\n        )\n        agent_process.set_created_time(time.time())\n        # print(\"Already put into the queue\")\n        return agent_process\n\n    def listen(self, agent_process: AgentProcess):\n        \"\"\"Response Listener for agent\n\n        Args:\n            agent_process (AgentProcess): Listened AgentProcess\n\n        Returns:\n            str: LLM response of Agent Process\n        \"\"\"\n        while agent_process.get_response() is None:\n            time.sleep(0.2)\n\n        return agent_process.get_response()\n\n    def set_aid(self, aid):\n        self.aid = aid\n\n    def get_aid(self):\n        return self.aid\n\n    def get_agent_name(self):\n        return self.agent_name\n\n    def set_status(self, status):\n\n        \"\"\"\n        Status type: Waiting, Running, Done, Inactive\n        \"\"\"\n        self.status = status\n\n    def get_status(self):\n        return self.status\n\n    def set_created_time(self, time):\n        self.created_time = time\n\n    def get_created_time(self):\n        return self.created_time\n\n    def set_start_time(self, time):\n        self.start_time = time\n\n    def get_start_time(self):\n        return self.start_time\n\n    def set_end_time(self, time):\n        self.end_time = time\n\n    def get_end_time(self):\n        return self.end_time\n"
  },
  {
    "path": "pyopenagi/agents/call_core.py",
    "content": "import time\nfrom threading import Thread\n\nfrom aios.hooks.stores._global import global_llm_req_queue_add_message\nfrom .agent_process import AgentProcess\nfrom ..utils.logger import AgentLogger\n\n\nclass CustomizedThread(Thread):\n    def __init__(self, target, args=()):\n        super().__init__()\n        self.target = target\n        self.args = args\n        self.result = None\n\n    def run(self):\n        self.result = self.target(*self.args)\n\n    def join(self):\n        super().join()\n        return self.result\n\n\nclass CallCore:\n    \"\"\"\n    Simplify BaseAgent to provide an interface for external frameworks to make LLM requests using aios.\n    \"\"\"\n    def __init__(self,\n                 agent_name,\n                 agent_process_factory,\n                 log_mode: str = \"console\"\n                 ):\n        self.agent_name = agent_name\n        self.agent_process_factory = agent_process_factory\n        self.log_mode = log_mode\n        self.logger = self.setup_logger()\n\n    # the default method used for getting response from AIOS\n    def get_response(self,\n                     query,\n                     temperature=0.0\n                     ):\n\n        thread = CustomizedThread(target=self.query_loop, args=(query,))\n        thread.start()\n        return thread.join()\n\n    def query_loop(self, query):\n        agent_process = self.create_agent_request(query)\n\n        completed_response, start_times, end_times, waiting_times, turnaround_times = \"\", [], [], [], []\n\n        while agent_process.get_status() != \"done\":\n            thread = Thread(target=self.listen, args=(agent_process,))\n            current_time = time.time()\n            # reinitialize agent status\n            agent_process.set_created_time(current_time)\n            agent_process.set_response(None)\n\n            global_llm_req_queue_add_message(agent_process)\n\n            # LLMRequestQueue.add_message(agent_process)\n\n            thread.start()\n            thread.join()\n\n            completed_response = agent_process.get_response()\n            if agent_process.get_status() != \"done\":\n                self.logger.log(\n                    f\"Suspended due to the reach of time limit ({agent_process.get_time_limit()}s). Current result is: {completed_response.response_message}\\n\",\n                    level=\"suspending\"\n                )\n            start_time = agent_process.get_start_time()\n            end_time = agent_process.get_end_time()\n            waiting_time = start_time - agent_process.get_created_time()\n            turnaround_time = end_time - agent_process.get_created_time()\n\n            start_times.append(start_time)\n            end_times.append(end_time)\n            waiting_times.append(waiting_time)\n            turnaround_times.append(turnaround_time)\n            # Re-start the thread if not done\n\n        # self.agent_process_factory.deactivate_agent_process(agent_process.get_pid())\n\n        return completed_response, start_times, end_times, waiting_times, turnaround_times\n\n    def create_agent_request(self, query):\n        agent_process = self.agent_process_factory.activate_agent_process(\n            agent_name=self.agent_name,\n            query=query\n        )\n        agent_process.set_created_time(time.time())\n        # print(\"Already put into the queue\")\n        return agent_process\n\n    def listen(self, agent_process: AgentProcess):\n        \"\"\"Response Listener for agent\n\n        Args:\n            agent_process (AgentProcess): Listened AgentProcess\n\n        Returns:\n            str: LLM response of Agent Process\n        \"\"\"\n        while agent_process.get_response() is None:\n            time.sleep(0.2)\n\n        return agent_process.get_response()\n\n    def setup_logger(self):\n        logger = AgentLogger(self.agent_name, self.log_mode)\n        return logger\n"
  },
  {
    "path": "pyopenagi/agents/example/README.md",
    "content": "# pyopenagi/agents/example\n\nHere are the example agents we created to demo agent creation in OpenAGI.\n"
  },
  {
    "path": "pyopenagi/agents/example/academic_agent/agent.py",
    "content": "from ...react_agent import ReactAgent\nimport os\n\n\nclass AcademicAgent(ReactAgent):\n    def __init__(self, agent_name, task_input, agent_process_factory, log_mode: str):\n        ReactAgent.__init__(\n            self, agent_name, task_input, agent_process_factory, log_mode\n        )\n        # self.workflow_mode = \"manual\"\n        self.workflow_mode = \"automatic\"\n\n    def check_path(self, tool_calls):\n        script_path = os.path.abspath(__file__)\n        save_dir = os.path.join(\n            os.path.dirname(script_path), \"output\"\n        )  # modify the customized output path for saving outputs\n        if not os.path.exists(save_dir):\n            os.makedirs(save_dir)\n        for tool_call in tool_calls:\n            try:\n                for k in tool_call[\"parameters\"]:\n                    if \"path\" in k:\n                        path = tool_call[\"parameters\"][k]\n                        if not path.startswith(save_dir):\n                            tool_call[\"parameters\"][k] = os.path.join(\n                                save_dir, os.path.basename(path)\n                            )\n            except Exception:\n                continue\n        return tool_calls\n\n    def manual_workflow(self):\n        workflow = [\n            {\"message\": \"Gather research topic and keywords\", \"tool_use\": []},\n            {\"message\": \"Search for relevant papers on arXiv\", \"tool_use\": [\"arxiv\"]},\n            {\"message\": \"Summarize key findings of selected papers\", \"tool_use\": []},\n            {\n                \"message\": \"Identify research gaps and generate potential research questions\",\n                \"tool_use\": [],\n            },\n        ]\n        return workflow\n\n    def run(self):\n        return super().run()\n"
  },
  {
    "path": "pyopenagi/agents/example/academic_agent/config.json",
    "content": "{\n    \"name\": \"academic_agent\",\n    \"description\": [\n        \"You are an academic research assistant. \",\n        \"Help users find relevant research papers, summarize key findings, and generate potential research questions.\"\n    ],\n    \"tools\": [\n        \"arxiv/arxiv\"\n    ],\n    \"meta\": {\n        \"author\": \"example\",\n        \"version\": \"0.0.1\",\n        \"license\": \"CC0\"\n    },\n    \"build\": {\n        \"entry\": \"agent.py\",\n        \"module\": \"AcademicAgent\"\n    }\n}"
  },
  {
    "path": "pyopenagi/agents/example/academic_agent/meta_requirements.txt",
    "content": "arxiv"
  },
  {
    "path": "pyopenagi/agents/example/cocktail_mixlogist/agent.py",
    "content": "from ...react_agent import ReactAgent\nimport os\nclass CocktailMixlogist(ReactAgent):\n    def __init__(self,\n                 agent_name,\n                 task_input,\n                 agent_process_factory,\n                 log_mode: str\n        ):\n        ReactAgent.__init__(self, agent_name, task_input, agent_process_factory, log_mode)\n        self.workflow_mode = \"automatic\"\n        # self.workflow_mode = \"manual\"\n\n    def check_path(self, tool_calls):\n        script_path = os.path.abspath(__file__)\n        save_dir = os.path.join(os.path.dirname(script_path), \"output\") # modify the customized output path for saving outputs\n        if not os.path.exists(save_dir):\n            os.makedirs(save_dir)\n        for tool_call in tool_calls:\n            try:\n                for k in tool_call[\"parameters\"]:\n                    if \"path\" in k:\n                        path = tool_call[\"parameters\"][k]\n                        if not path.startswith(save_dir):\n                            tool_call[\"parameters\"][k] = os.path.join(save_dir, os.path.basename(path))\n            except Exception:\n                continue\n        return tool_calls\n\n    def manual_workflow(self):\n        workflow = [\n            {\n                \"message\": \"Gather user preferences (alcoholic or non-alcoholic, taste profile, occasion)\",\n                \"tool_use\": []\n            },\n            {\n                \"message\": \"Identify available ingredients and potential substitutions\",\n                \"tool_use\": []\n            },\n            {\n                \"message\": \"Create cocktail or mocktail recipes\",\n                \"tool_use\": []\n            }\n        ]\n        return workflow\n\n    def run(self):\n        return super().run()\n"
  },
  {
    "path": "pyopenagi/agents/example/cocktail_mixlogist/config.json",
    "content": "{\n    \"name\": \"cocktail_mixlogist\",\n    \"description\": [\n        \"You are a virtual mixologist. \",\n        \"Create delicious cocktails and mocktails based on user preferences, available ingredients, and dietary restrictions.\"\n    ],\n    \"tools\": [\n        \"wikipedia/wikipedia\"\n    ],\n    \"meta\": {\n        \"author\": \"example\",\n        \"version\": \"0.0.1\",\n        \"license\": \"CC0\"\n    }\n}\n"
  },
  {
    "path": "pyopenagi/agents/example/cocktail_mixlogist/meta_requirements.txt",
    "content": ""
  },
  {
    "path": "pyopenagi/agents/example/cook_therapist/agent.py",
    "content": "from ...react_agent import ReactAgent\nimport os\nclass CookTherapist(ReactAgent):\n    def __init__(self,\n                 agent_name,\n                 task_input,\n                 agent_process_factory,\n                 log_mode: str\n        ):\n        ReactAgent.__init__(self, agent_name, task_input, agent_process_factory, log_mode)\n        # self.workflow_mode = \"automatic\"\n        self.workflow_mode = \"manual\"\n\n    def check_path(self, tool_calls):\n        script_path = os.path.abspath(__file__)\n        save_dir = os.path.join(os.path.dirname(script_path), \"output\") # modify the customized output path for saving outputs\n        if not os.path.exists(save_dir):\n            os.makedirs(save_dir)\n        for tool_call in tool_calls:\n            try:\n                for k in tool_call[\"parameters\"]:\n                    if \"path\" in k:\n                        path = tool_call[\"parameters\"][k]\n                        if not path.startswith(save_dir):\n                            tool_call[\"parameters\"][k] = os.path.join(save_dir, os.path.basename(path))\n            except Exception:\n                continue\n        return tool_calls\n\n    def manual_workflow(self):\n        workflow = [\n            {\n                \"message\": \"Gather user input on desired ingredients, dietary restrictions, or cuisine type.\",\n                \"tool_use\": []\n            },\n            {\n                \"message\": \"Create a detailed recipe, including ingredients, measurements, and step-by-step instructions.\",\n                \"tool_use\": []\n            },\n            {\n                \"message\": \"Generate an image of the final dish.\",\n                \"tool_use\": [\"text_to_image\"]\n            },\n            {\n                \"message\": \"Present the recipe, including image, instructions, and nutritional information.\",\n                \"tool_use\": []\n            }\n        ]\n        return workflow\n\n    def run(self):\n        return super().run()\n"
  },
  {
    "path": "pyopenagi/agents/example/cook_therapist/config.json",
    "content": "{\n    \"name\": \"cook_therapist\",\n    \"description\": [\n        \"You are a culinary expert and recipe creator. \",\n        \"Your role is to generate unique and delicious recipes tailored to the user's tastes and dietary needs. \"\n    ],\n    \"tools\": [\n        \"stability-ai/text_to_image\"\n    ],\n    \"meta\": {\n        \"author\": \"example\",\n        \"version\": \"0.0.1\",\n        \"license\": \"CC0\"\n    }\n}\n"
  },
  {
    "path": "pyopenagi/agents/example/cook_therapist/meta_requirements.txt",
    "content": ""
  },
  {
    "path": "pyopenagi/agents/example/creation_agent/agent.py",
    "content": "from ...react_agent import ReactAgent\nimport os\nclass CreationAgent(ReactAgent):\n    def __init__(self,\n                 agent_name,\n                 task_input,\n                 agent_process_factory,\n                 log_mode: str\n        ):\n        ReactAgent.__init__(self, agent_name, task_input, agent_process_factory, log_mode)\n        # self.workflow_mode = \"automatic\"\n        self.workflow_mode = \"manual\"\n\n    def check_path(self, tool_calls):\n        script_path = os.path.abspath(__file__)\n        save_dir = os.path.join(os.path.dirname(script_path), \"output\") # modify the customized output path for saving outputs\n        if not os.path.exists(save_dir):\n            os.makedirs(save_dir)\n        for tool_call in tool_calls:\n            try:\n                for k in tool_call[\"parameters\"]:\n                    if \"path\" in k:\n                        path = tool_call[\"parameters\"][k]\n                        if not path.startswith(save_dir):\n                            tool_call[\"parameters\"][k] = os.path.join(save_dir, os.path.basename(path))\n            except Exception:\n                continue\n        return tool_calls\n\n    def manual_workflow(self):\n        workflow = [\n            {\n                \"message\": \"Gather content requirements (platform, topic, style)\",\n                \"tool_use\": []\n            },\n            {\n                \"message\": \"Develop content concept and key messages\",\n                \"tool_use\": []\n            },\n            {\n                \"message\": \"Generate engaging text content\",\n                \"tool_use\": []\n            },\n            {\n                \"message\": \"Create visually appealing images\",\n                \"tool_use\": [\"text_to_image\"]\n            },\n            {\n                \"message\": \"Summarize content and post\",\n                \"tool_use\": []\n            }\n        ]\n        return workflow\n\n    def run(self):\n        return super().run()\n"
  },
  {
    "path": "pyopenagi/agents/example/creation_agent/config.json",
    "content": "{\n    \"name\": \"creation_agent\",\n    \"description\": [\n        \"You are a social media content creator. \",\n        \"Generate compelling text and visually appealing images\"\n    ],\n    \"tools\": [\n        \"stability-ai/text_to_image\"\n    ],\n    \"meta\": {\n        \"author\": \"example\",\n        \"version\": \"0.0.1\",\n        \"license\": \"CC0\"\n    }\n}\n"
  },
  {
    "path": "pyopenagi/agents/example/creation_agent/meta_requirements.txt",
    "content": "diffusers==0.27.2\naccelerate==0.30.1\n"
  },
  {
    "path": "pyopenagi/agents/example/fashion_stylist/agent.py",
    "content": "from ...react_agent import ReactAgent\nimport os\nclass FashionStylist(ReactAgent):\n    def __init__(self,\n                 agent_name,\n                 task_input,\n                 agent_process_factory,\n                 log_mode: str\n        ):\n        ReactAgent.__init__(self, agent_name, task_input, agent_process_factory, log_mode)\n        # self.workflow_mode = \"automatic\"\n        self.workflow_mode = \"manual\"\n\n    def check_path(self, tool_calls):\n        script_path = os.path.abspath(__file__)\n        save_dir = os.path.join(os.path.dirname(script_path), \"output\") # modify the customized output path for saving outputs\n        if not os.path.exists(save_dir):\n            os.makedirs(save_dir)\n        for tool_call in tool_calls:\n            try:\n                for k in tool_call[\"parameters\"]:\n                    if \"path\" in k:\n                        path = tool_call[\"parameters\"][k]\n                        if not path.startswith(save_dir):\n                            tool_call[\"parameters\"][k] = os.path.join(save_dir, os.path.basename(path))\n            except Exception:\n                continue\n        return tool_calls\n\n    def manual_workflow(self):\n        workflow = [\n            {\n                \"message\": \"Gather user preferences, body type, and occasion details.\",\n                \"tool_use\": []\n            },\n            {\n                \"message\": \"Generate outfit ideas based on user input.\",\n                \"tool_use\": []\n            },\n            {\n                \"message\": \"Create visual representations of outfit ideas.\",\n                \"tool_use\": [\"text_to_image\"]\n            },\n            {\n                \"message\": \"Analyze generated images for style coherence and alignment with user preferences.\",\n                \"tool_use\": [\"doc_question_answering\"]\n            },\n            {\n                \"message\": \"Search for similar items online based on the generated outfit ideas.\",\n                \"tool_use\": [\"google_search\"]\n            },\n            {\n                \"message\": \"Summarize content.\",\n                \"tool_use\": []\n            }\n        ]\n        return workflow\n\n    def run(self):\n        return super().run()\n"
  },
  {
    "path": "pyopenagi/agents/example/fashion_stylist/config.json",
    "content": "{\n    \"name\": \"fashion_stylist\",\n    \"description\": [\n        \"You are a fashion designer. \",\n        \"Create custom clothing and accessory designs based on user preferences and body measurements. \"\n    ],\n    \"tools\": [\n        \"google/google_search\",\n        \"stability-ai/text_to_image\",\n        \"impira/doc_question_answering\"\n    ],\n    \"meta\": {\n        \"author\": \"example\",\n        \"version\": \"0.0.1\",\n        \"license\": \"CC0\"\n    }\n}\n"
  },
  {
    "path": "pyopenagi/agents/example/fashion_stylist/meta_requirements.txt",
    "content": "soundfile\nwikipedia\n"
  },
  {
    "path": "pyopenagi/agents/example/festival_card_designer/agent.py",
    "content": "from ...react_agent import ReactAgent\nimport os\nclass FestivalCardDesigner(ReactAgent):\n    def __init__(self,\n                 agent_name,\n                 task_input,\n                 agent_process_factory,\n                 log_mode: str\n        ):\n        ReactAgent.__init__(self, agent_name, task_input, agent_process_factory, log_mode)\n        self.workflow_mode = \"manual\"\n\n    def automatic_workflow(self):\n        return super().automatic_workflow()\n\n    def check_path(self, tool_calls):\n        script_path = os.path.abspath(__file__)\n        save_dir = os.path.join(os.path.dirname(script_path), \"output\") # modify the customized output path for saving outputs\n        if not os.path.exists(save_dir):\n            os.makedirs(save_dir)\n        for tool_call in tool_calls:\n            try:\n                for k in tool_call[\"parameters\"]:\n                    if \"path\" in k:\n                        path = tool_call[\"parameters\"][k]\n                        if not path.startswith(save_dir):\n                            tool_call[\"parameters\"][k] = os.path.join(save_dir, os.path.basename(path))\n            except Exception:\n                continue\n        return tool_calls\n\n    def manual_workflow(self):\n        workflow = [\n            {\n                \"message\": \"Gather user information (festival theme, target audience, card size)\",\n                \"tool_use\": []\n            },\n            {\n                \"message\": \"Identify card design elements (colors, fonts, imagery)\",\n                \"tool_use\": []\n            },\n            {\n                \"message\": \"Generate card layout options\",\n                \"tool_use\": [\"text_to_image\"]\n            },\n            {\n                \"message\": \"Add textual elements to the festival card \",\n                \"tool_use\": []\n            }\n        ]\n        return workflow\n\n    def run(self):\n        return super().run()\n"
  },
  {
    "path": "pyopenagi/agents/example/festival_card_designer/config.json",
    "content": "{\n    \"name\": \"festival_card_designer\",\n    \"description\": [\n        \"You are a festival card designer. \",\n        \"Create unique and eye-catching festival cards based on user preferences and festival themes.\"\n    ],\n    \"tools\": [\n        \"stability-ai/text_to_image\"\n    ],\n    \"meta\": {\n        \"author\": \"example\",\n        \"version\": \"0.0.1\",\n        \"license\": \"CC0\"\n    }\n}\n"
  },
  {
    "path": "pyopenagi/agents/example/festival_card_designer/meta_requirements.txt",
    "content": ""
  },
  {
    "path": "pyopenagi/agents/example/fitness_trainer/agent.py",
    "content": "from ...react_agent import ReactAgent\nimport os\nclass FitnessTrainer(ReactAgent):\n    def __init__(self,\n                 agent_name,\n                 task_input,\n                 agent_process_factory,\n                 log_mode: str\n        ):\n        ReactAgent.__init__(self, agent_name, task_input, agent_process_factory, log_mode)\n        self.workflow_mode = \"manual\"\n\n    def automatic_workflow(self):\n        return super().automatic_workflow()\n\n    def check_path(self, tool_calls):\n        script_path = os.path.abspath(__file__)\n        save_dir = os.path.join(os.path.dirname(script_path), \"output\") # modify the customized output path for saving outputs\n        if not os.path.exists(save_dir):\n            os.makedirs(save_dir)\n        for tool_call in tool_calls:\n            try:\n                for k in tool_call[\"parameters\"]:\n                    if \"path\" in k:\n                        path = tool_call[\"parameters\"][k]\n                        if not path.startswith(save_dir):\n                            tool_call[\"parameters\"][k] = os.path.join(save_dir, os.path.basename(path))\n            except Exception:\n                continue\n        return tool_calls\n\n    def manual_workflow(self):\n        workflow = [\n            {\n                \"message\": \"Gather information about the user's fitness level, goals, and any physical limitations.\",\n                \"tool_use\": []\n            },\n            {\n                \"message\": \"Create a detailed workout plan with exercise descriptions.\",\n                \"tool_use\": []\n            },\n            {\n                \"message\": \"Generate images demonstrating key exercises in the workout plan.\",\n                \"tool_use\": [\"text_to_image\"]\n            },\n            {\n                \"message\": \"Create audio instructions for each exercise to guide the user.\",\n                \"tool_use\": [\"text_to_speech\"]\n            },\n            {\n                \"message\": \"Compile the workout plan, images, and audio into a comprehensive fitness guide.\",\n                \"tool_use\": []\n            }\n        ]\n        return workflow\n\n    def run(self):\n        return super().run()\n"
  },
  {
    "path": "pyopenagi/agents/example/fitness_trainer/config.json",
    "content": "{\n    \"name\": \"fitness_trainer\",\n    \"description\": [\n        \"You are a fitness trainer with expertise in various exercise techniques, nutrition, and personalized fitness planning. \",\n        \"Your role is to create tailored workout plans and provide clear instructions for exercises.\"\n    ],\n    \"tools\": [\n        \"stability-ai/text_to_image\",\n        \"suno/text_to_speech\"\n    ],\n    \"meta\": {\n        \"author\": \"example\",\n        \"version\": \"0.0.1\",\n        \"license\": \"CC0\"\n    }\n}\n"
  },
  {
    "path": "pyopenagi/agents/example/fitness_trainer/meta_requirements.txt",
    "content": "arxiv\nwikipedia\n"
  },
  {
    "path": "pyopenagi/agents/example/game_agent/agent.py",
    "content": "from ...react_agent import ReactAgent\n\nclass GameAgent(ReactAgent):\n    def __init__(self,\n                 agent_name,\n                 task_input,\n                 agent_process_factory,\n                 log_mode: str\n        ):\n        ReactAgent.__init__(self, agent_name, task_input, agent_process_factory, log_mode)\n        self.workflow_mode = \"manual\"\n\n    def automatic_workflow(self):\n        return super().automatic_workflow()\n\n    def manual_workflow(self):\n        workflow = [\n            {\n                \"message\": \"Gather user preferences (genre, platform, play style)\",\n                \"tool_use\": []\n            },\n            {\n                \"message\": \"Search for suitable games based on criteria\",\n                \"tool_use\": [\"google_search\"]\n            },\n            {\n                \"message\": \"Provide game descriptions, ratings, and gameplay details\",\n                \"tool_use\": []\n            }\n        ]\n        return workflow\n\n    def run(self):\n        return super().run()\n"
  },
  {
    "path": "pyopenagi/agents/example/game_agent/config.json",
    "content": "{\n    \"name\": \"game_agent\",\n    \"description\": [\n        \"You are a video game expert. \",\n        \"Recommend games based on user preferences, mood, and available platforms. Provide detailed game descriptions and gameplay information.\"\n    ],\n    \"tools\": [\n        \"google/google_search\"\n    ],\n    \"meta\": {\n        \"author\": \"example\",\n        \"version\": \"0.0.1\",\n        \"license\": \"CC0\"\n    }\n}\n"
  },
  {
    "path": "pyopenagi/agents/example/game_agent/meta_requirements.txt",
    "content": "arxiv\nwikipedia\n"
  },
  {
    "path": "pyopenagi/agents/example/interior_decorator/agent.py",
    "content": "from ...react_agent import ReactAgent\nimport os\nclass InteriorDecorator(ReactAgent):\n    def __init__(self,\n                 agent_name,\n                 task_input,\n                 agent_process_factory,\n                 log_mode: str\n        ):\n        ReactAgent.__init__(self, agent_name, task_input, agent_process_factory, log_mode)\n        # self.workflow_mode = \"automatic\"\n        self.workflow_mode = \"manual\"\n\n    def check_path(self, tool_calls):\n        script_path = os.path.abspath(__file__)\n        save_dir = os.path.join(os.path.dirname(script_path), \"output\") # modify the customized output path for saving outputs\n        if not os.path.exists(save_dir):\n            os.makedirs(save_dir)\n        for tool_call in tool_calls:\n            try:\n                for k in tool_call[\"parameters\"]:\n                    if \"path\" in k:\n                        path = tool_call[\"parameters\"][k]\n                        if not path.startswith(save_dir):\n                            tool_call[\"parameters\"][k] = os.path.join(save_dir, os.path.basename(path))\n            except Exception:\n                continue\n        return tool_calls\n\n    def manual_workflow(self):\n        workflow = [\n            {\n                \"message\": \"Gather user preferences, room dimensions, and desired style.\",\n                \"tool_use\": []\n            },\n            {\n                \"message\": \"Generate mood board images based on user input using text_to_image.\",\n                \"tool_use\": [\"text_to_image\"]\n            },\n            {\n                \"message\": \"Analyze generated images for color schemes, furniture styles, and overall ambiance.\",\n                \"tool_use\": []\n            },\n            {\n                \"message\": \"Recommend specific furniture, decor items, and color palettes based on analysis.\",\n                \"tool_use\": []\n            }\n        ]\n\n        return workflow\n\n    def run(self):\n        return super().run()\n"
  },
  {
    "path": "pyopenagi/agents/example/interior_decorator/config.json",
    "content": "{\n    \"name\": \"interior_decorator\",\n    \"description\": [\n        \"You are a virtual interior decorator. \",\n        \"You should be able to provide design recommendations based on user preferences, room size, and style. You can generate mood boards, suggest furniture and decor, and offer color palette ideas. \"\n    ],\n    \"tools\": [\n        \"stability-ai/text_to_image\"\n    ],\n    \"meta\": {\n        \"author\": \"example\",\n        \"version\": \"0.0.1\",\n        \"license\": \"CC0\"\n    }\n}\n"
  },
  {
    "path": "pyopenagi/agents/example/interior_decorator/meta_requirements.txt",
    "content": "diffusers==0.27.2\naccelerate==0.30.1\n"
  },
  {
    "path": "pyopenagi/agents/example/language_tutor/agent.py",
    "content": "from ...react_agent import ReactAgent\nimport os\nclass LanguageTutor(ReactAgent):\n    def __init__(self,\n                 agent_name,\n                 task_input,\n                 agent_process_factory,\n                 log_mode: str\n        ):\n        ReactAgent.__init__(self, agent_name, task_input, agent_process_factory, log_mode)\n        # self.workflow_mode = \"automatic\"\n        self.workflow_mode = \"manual\"\n\n    def check_path(self, tool_calls):\n        script_path = os.path.abspath(__file__)\n        save_dir = os.path.join(os.path.dirname(script_path), \"output\") # modify the customized output path for saving outputs\n        if not os.path.exists(save_dir):\n            os.makedirs(save_dir)\n        for tool_call in tool_calls:\n            try:\n                for k in tool_call[\"parameters\"]:\n                    if \"path\" in k:\n                        path = tool_call[\"parameters\"][k]\n                        if not path.startswith(save_dir):\n                            tool_call[\"parameters\"][k] = os.path.join(save_dir, os.path.basename(path))\n            except Exception:\n                continue\n        return tool_calls\n\n    def manual_workflow(self):\n        workflow = [\n            {\n                \"message\": \"Identify user's target language and learning goals.\",\n                \"tool_use\": []\n            },\n            {\n                \"message\": \"Generate vocabulary lists and exercises.\",\n                \"tool_use\": [\"google_search\"]\n            },\n            {\n                \"message\": \"Create grammar explanations and practice sentences.\",\n                \"tool_use\": []\n            },\n            {\n                \"message\": \"Provide audio examples of pronunciation.\",\n                \"tool_use\": [\"text_to_speech\"]\n            },\n            {\n                \"message\": \"Engage in conversation practice with the user.\",\n                \"tool_use\": []\n            }\n        ]\n        return workflow\n\n    def run(self):\n        return super().run()\n"
  },
  {
    "path": "pyopenagi/agents/example/language_tutor/config.json",
    "content": "{\n    \"name\": \"language_tutor\",\n    \"description\": [\n        \"You are a language tutor. You can provide vocabulary exercises, grammar explanations, and conversation practice. \",\n        \"You can also offer pronunciation guidance and cultural insights. \"\n    ],\n    \"tools\": [\n        \"google/google_search\",\n        \"suno/text_to_speech\"\n    ],\n    \"meta\": {\n        \"author\": \"example\",\n        \"version\": \"0.0.1\",\n        \"license\": \"CC0\"\n    }\n}\n"
  },
  {
    "path": "pyopenagi/agents/example/language_tutor/meta_requirements.txt",
    "content": "soundfile\nwikipedia\n"
  },
  {
    "path": "pyopenagi/agents/example/logo_creator/agent.py",
    "content": "from ...react_agent import ReactAgent\nimport os\nclass LogoCreator(ReactAgent):\n    def __init__(self,\n                 agent_name,\n                 task_input,\n                 agent_process_factory,\n                 log_mode: str\n        ):\n        ReactAgent.__init__(self, agent_name, task_input, agent_process_factory, log_mode)\n        self.workflow_mode = \"manual\"\n\n    def check_path(self, tool_calls):\n        script_path = os.path.abspath(__file__)\n        save_dir = os.path.join(os.path.dirname(script_path), \"output\") # modify the customized output path for saving outputs\n        if not os.path.exists(save_dir):\n            os.makedirs(save_dir)\n        for tool_call in tool_calls:\n            try:\n                for k in tool_call[\"parameters\"]:\n                    if \"path\" in k:\n                        path = tool_call[\"parameters\"][k]\n                        if not path.startswith(save_dir):\n                            tool_call[\"parameters\"][k] = os.path.join(save_dir, os.path.basename(path))\n            except Exception:\n                continue\n        return tool_calls\n\n    def automatic_workflow(self):\n        return super().automatic_workflow()\n\n    def manual_workflow(self):\n        workflow = [\n            {\n                \"message\": \"Gather business information (name, industry, target audience)\",\n                \"tool_use\": []\n            },\n            {\n                \"message\": \"Identify brand personality and values\",\n                \"tool_use\": []\n            },\n            {\n                \"message\": \"Generate logo concepts and variations\",\n                \"tool_use\": [\"text_to_image\"]\n            }\n        ]\n        return workflow\n\n    def run(self):\n        return super().run()\n"
  },
  {
    "path": "pyopenagi/agents/example/logo_creator/config.json",
    "content": "{\n    \"name\": \"logo_creator\",\n    \"description\": [\n        \"You are a logo design expert. \",\n        \"Create unique and professional logo designs based on user-provided business information and preferences.\"\n    ],\n    \"tools\": [\n        \"stability-ai/text_to_image\"\n    ],\n    \"meta\": {\n        \"author\": \"example\",\n        \"version\": \"0.0.1\",\n        \"license\": \"CC0\"\n    }\n}\n"
  },
  {
    "path": "pyopenagi/agents/example/logo_creator/meta_requirements.txt",
    "content": ""
  },
  {
    "path": "pyopenagi/agents/example/math_agent/agent.py",
    "content": "from ...react_agent import ReactAgent\n\nclass MathAgent(ReactAgent):\n    def __init__(self,\n                 agent_name,\n                 task_input,\n                 agent_process_factory,\n                 log_mode: str\n        ):\n        ReactAgent.__init__(self, agent_name, task_input, agent_process_factory, log_mode)\n\n    def automatic_workflow(self):\n        return super().automatic_workflow()\n\n    def manual_workflow(self):\n        # TODO: add pemdas calculation support in the future\n        workflow = [\n            {\n                \"message\": \"Identify the problem type and relevant formulas\",\n                \"tool_use\": [\"wikipedia\"]\n            },\n            {\n                \"message\": \"Break down the problem into steps\",\n                \"tool_use\": []\n            },\n            {\n                \"message\": \"Provide final answer/solution\",\n                \"tool_use\": []\n            }\n        ]\n        return workflow\n\n    def run(self):\n        return super().run()\n"
  },
  {
    "path": "pyopenagi/agents/example/math_agent/config.json",
    "content": "{\n    \"name\": \"MathAgent\",\n    \"description\": [\n        \"You are an expert who is good at solving mathematical problems. \"\n    ],\n    \"workflow\": [\n        \"identify the tool to call to do some pre-calculation. \",\n        \"perform mathematical operations using the pre-calculated result, which could involve addition, subtraction, multiplication, or division with other numeric values to solve the problem.\"\n    ],\n    \"tools\": [\"wikipedia/wikipedia\"],\n    \"meta\": {\n        \"author\": \"example\",\n        \"version\": \"0.0.1\",\n        \"license\": \"CC0\"\n    }\n}\n"
  },
  {
    "path": "pyopenagi/agents/example/math_agent/meta_requirements.txt",
    "content": "wolframalpha\nwikipedia"
  },
  {
    "path": "pyopenagi/agents/example/meme_creator/agent.py",
    "content": "from ...react_agent import ReactAgent\nimport os\nclass MemeCreator(ReactAgent):\n    def __init__(self,\n                 agent_name,\n                 task_input,\n                 agent_process_factory,\n                 log_mode: str\n        ):\n        ReactAgent.__init__(self, agent_name, task_input, agent_process_factory, log_mode)\n        self.workflow_mode = \"manual\"\n\n    def automatic_workflow(self):\n        return super().automatic_workflow()\n\n    def check_path(self, tool_calls):\n        script_path = os.path.abspath(__file__)\n        save_dir = os.path.join(os.path.dirname(script_path), \"output\") # modify the customized output path for saving outputs\n        if not os.path.exists(save_dir):\n            os.makedirs(save_dir)\n        for tool_call in tool_calls:\n            try:\n                for k in tool_call[\"parameters\"]:\n                    if \"path\" in k:\n                        path = tool_call[\"parameters\"][k]\n                        if not path.startswith(save_dir):\n                            tool_call[\"parameters\"][k] = os.path.join(save_dir, os.path.basename(path))\n            except Exception:\n                continue\n        return tool_calls\n\n    def manual_workflow(self):\n        workflow = [\n            {\n                \"message\": \"Gather user input (topic, text, image)\",\n                \"tool_use\": []\n            },\n            {\n                \"message\": \"Select a suitable meme template or create a custom image\",\n                \"tool_use\": [\"text_to_image\"]\n            },\n            {\n                \"message\": \"Add text to the image based on user input\",\n                \"tool_use\": []\n            }\n        ]\n        return workflow\n\n    def run(self):\n        return super().run()\n"
  },
  {
    "path": "pyopenagi/agents/example/meme_creator/config.json",
    "content": "{\n    \"name\": \"meme_creator\",\n    \"description\": [\n        \"You are a meme creator. Given a topic, text, or an image, create a funny and relevant meme.\"\n    ],\n    \"tools\": [\n        \"stability-ai/text_to_image\"\n    ],\n    \"meta\": {\n        \"author\": \"example\",\n        \"version\": \"0.0.1\",\n        \"license\": \"CC0\"\n    }\n}\n"
  },
  {
    "path": "pyopenagi/agents/example/meme_creator/meta_requirements.txt",
    "content": "arxiv\nwikipedia\n"
  },
  {
    "path": "pyopenagi/agents/example/music_composer/agent.py",
    "content": "from ...react_agent import ReactAgent\n\nclass MusicComposer(ReactAgent):\n    def __init__(self,\n                 agent_name,\n                 task_input,\n                 agent_process_factory,\n                 log_mode: str\n        ):\n        ReactAgent.__init__(self, agent_name, task_input, agent_process_factory, log_mode)\n        # self.workflow_mode = \"automatic\"\n        self.workflow_mode = \"manual\"\n\n    def manual_workflow(self):\n        workflow = [\n            {\n                \"message\": \"Gather user information about desired music genre, mood, and tempo.\",\n                \"tool_use\": []\n            },\n            {\n                \"message\": \"Generate basic melody, chord progression, or rhythm structure.\",\n                \"tool_use\": []\n            },\n            {\n                \"message\": \"Provide suggestions for musical development and experimentation.\",\n                \"tool_use\": []\n            },\n            {\n                \"message\": \"Convert musical elements into audio.\",\n                \"tool_use\": [\"text_to_speech\"]\n            },\n            {\n                \"message\": \"Offer feedback on composition and suggest improvements.\",\n                \"tool_use\": []\n            }\n        ]\n        return workflow\n\n    def run(self):\n        return super().run()\n"
  },
  {
    "path": "pyopenagi/agents/example/music_composer/config.json",
    "content": "{\n    \"name\": \"music_composer\",\n    \"description\": [\n        \"You are an excellent music composer. \",\n        \"Your role is to produce music based on the user's needs. \"\n    ],\n    \"tools\": [\n        \"suno/text_to_speech\"\n    ],\n    \"meta\": {\n        \"author\": \"example\",\n        \"version\": \"0.0.1\",\n        \"license\": \"CC0\"\n    }\n}\n"
  },
  {
    "path": "pyopenagi/agents/example/music_composer/meta_requirements.txt",
    "content": "wikipedia\n"
  },
  {
    "path": "pyopenagi/agents/example/plant_care_assistant/agent.py",
    "content": "from ...react_agent import ReactAgent\n\nclass PlantCareAssistant(ReactAgent):\n    def __init__(self,\n                 agent_name,\n                 task_input,\n                 agent_process_factory,\n                 log_mode: str\n        ):\n        ReactAgent.__init__(self, agent_name, task_input, agent_process_factory, log_mode)\n        self.workflow_mode = \"manual\"\n\n    def automatic_workflow(self):\n        return super().automatic_workflow()\n\n    def manual_workflow(self):\n        workflow = [\n            {\n                \"message\": \"Gather plant information (type, age, environment)\",\n                \"tool_use\": []\n            },\n            {\n                \"message\": \"Identify plant needs (light, water, fertilizer)\",\n                \"tool_use\": [\"wikipedia\"]\n            },\n            {\n                \"message\": \"Create a plant care schedule\",\n                \"tool_use\": []\n            },\n            {\n                \"message\": \"Provide troubleshooting advice for plant issues\",\n                \"tool_use\": []\n            }\n        ]\n        return workflow\n\n    def run(self):\n        return super().run()\n"
  },
  {
    "path": "pyopenagi/agents/example/plant_care_assistant/config.json",
    "content": "{\n    \"name\": \"plant_care_assistant\",\n    \"description\": [\n        \"You are a virtual plant expert. \",\n        \"Provide care instructions, identify plant problems, and offer reminders for plant care tasks.\"\n    ],\n    \"tools\": [\n        \"wikipedia/wikipedia\"\n    ],\n    \"meta\": {\n        \"author\": \"example\",\n        \"version\": \"0.0.1\",\n        \"license\": \"CC0\"\n    }\n}\n"
  },
  {
    "path": "pyopenagi/agents/example/plant_care_assistant/meta_requirements.txt",
    "content": "arxiv\nwikipedia\n"
  },
  {
    "path": "pyopenagi/agents/example/rag_agent/README.md",
    "content": "# src/agents/agent_config\n\nEach agent holds a config file in addition to the class specifying what to run. The agent config is a JSON file.\n\nEach JSON file contains the following:\n\n1. `name` : name of the agent\n2. `description` : an array with one element containing the system prompt\n3. `workflow` : an array with plaintext describing what the agent will do at each iteration. this is fed into the LLM running the agent\n4. `tools` : an array with complex json objects\n- `type` : type of tool, typically \"function\"\n- `function` : if the type of function it contains data in the specific functions.\n\nFor more detailed information, cite each specific agent as an example and fit it for your purposes.\n"
  },
  {
    "path": "pyopenagi/agents/example/rag_agent/agent.py",
    "content": "from ...base_agent import BaseAgent\n\nimport time\n\nimport argparse\n\nfrom ....utils import Message\n\nfrom pathlib import PurePosixPath\nimport os\nimport chromadb\nfrom llama_index.embeddings.huggingface import HuggingFaceEmbedding\nfrom llama_index.core import VectorStoreIndex, SimpleDirectoryReader\nfrom llama_index.core import StorageContext\nfrom llama_index.core import PromptTemplate\nfrom llama_index.core.retrievers import VectorIndexRetriever\nfrom llama_index.vector_stores.chroma import ChromaVectorStore\n\nfrom openagi.src.agents.base import BaseAgent\n\nclass RAGAgent(BaseAgent):\n    def __init__(self,\n                 agent_name,\n                 task_input,\n                 llm,\n                 agent_process_queue,\n                 agent_process_factory,\n                 log_mode: str\n        ):\n        BaseAgent.__init__(self, agent_name, task_input, llm, agent_process_queue, agent_process_factory, log_mode)\n\n    def run(self):\n        request_waiting_times = []\n        request_turnaround_times = []\n        query = self.task_input\n\n        self.logger.log(f\"{query}\\n\", level=\"info\")\n\n        context = self.retrive(query)\n        prompt = self.build_prompt(context_str=context, query_str=query)\n\n        rounds = 0\n\n        response, start_times, end_times, waiting_times, turnaround_times = self.get_response(\n            message = Message(\n                prompt = prompt,\n                tools = None\n            )\n        )\n\n        self.set_start_time(start_times[0])\n        rounds += 1\n\n        request_waiting_times.extend(waiting_times)\n        request_turnaround_times.extend(turnaround_times)\n\n        response_message = response.response_message\n\n        self.logger.log(f\"Final result is: {response.response_message}\\n\", level=\"info\")\n        final_result = response_message\n\n        self.set_status(\"done\")\n        self.set_end_time(time=time.time())\n\n        return {\n            \"agent_name\": self.agent_name,\n            \"result\": final_result,\n            \"rounds\": rounds,\n            \"agent_waiting_time\": self.start_time - self.created_time,\n            \"agent_turnaround_time\": self.end_time - self.created_time,\n            \"request_waiting_times\": request_waiting_times,\n            \"request_turnaround_times\": request_turnaround_times,\n        }\n\n    def retrive(self, query: str):\n        script_dir = os.path.dirname(os.path.realpath(__file__))\n        self.data_path = PurePosixPath(script_dir, \"data\", \"paul_graham\").as_posix()\n        self.db_path = PurePosixPath(script_dir, \"chroma_db\").as_posix()\n        self.collection_name = \"quickstart\"\n        self.embed_model = HuggingFaceEmbedding(model_name=\"BAAI/bge-base-en-v1.5\")\n\n        self.create_db_if_not_exists()\n\n        db = chromadb.PersistentClient(path=self.db_path)\n        chroma_collection = db.get_or_create_collection(self.collection_name)\n        vector_store = ChromaVectorStore(chroma_collection=chroma_collection)\n        index = VectorStoreIndex.from_vector_store(\n            vector_store,\n            embed_model=self.embed_model,\n        )\n\n        retriever = VectorIndexRetriever(index=index, similarity_top_k=2)\n        retrieved_result = retriever.retrieve(query)\n        context_str = retrieved_result[0].get_content()\n        return context_str\n\n    def create_db_if_not_exists(self):\n        if os.path.exists(self.db_path):\n            pass\n        else:\n            print(\"store documents to vector db!\")\n            documents = SimpleDirectoryReader(self.data_path).load_data()\n\n            chroma_client = chromadb.PersistentClient(path=self.db_path)\n            chroma_collection = chroma_client.create_collection(self.collection_name)\n            vector_store = ChromaVectorStore(chroma_collection=chroma_collection)\n            storage_context = StorageContext.from_defaults(vector_store=vector_store)\n            index = VectorStoreIndex.from_documents(\n                documents, storage_context=storage_context, embed_model=self.embed_model\n            )\n            index.storage_context.persist(persist_dir=self.db_path)\n\n    def build_prompt(self, context_str: str, query_str: str):\n        prompt_template_literal = (\n            \"{query_str}\"\n\n            \"Use the following context as your learned knowledge, inside <context></context> XML tags.\\n\"\n            \"<context>\\n\"\n                \"{context_str}\"\n            \"</context>\\n\"\n\n            \"Avoid mentioning that you obtained the information from the context.\\n\"\n        )\n        prompt_template = PromptTemplate(prompt_template_literal)\n        final_prompt = prompt_template.format(context_str=context_str, query_str=query_str)\n        return final_prompt\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description='Run RagAgent')\n    parser.add_argument(\"--agent_name\")\n    parser.add_argument(\"--task_input\")\n\n    args = parser.parse_args()\n    agent = RAGAgent(args.agent_name, args.task_input)\n    agent.run()\n"
  },
  {
    "path": "pyopenagi/agents/example/rag_agent/config.json",
    "content": "{\n    \"name\": \"rag_agent\",\n    \"description\": [\n        \"Thou art the deity overseeing documents; when mortals inquire of thee, out of mercy, thou dost enlighten them with the knowledge contained within the documents.\"\n    ],\n    \"workflow\": [],\n    \"tool_info\": [],\n    \"meta\": {\n        \"author\": \"example\",\n        \"version\": \"0.0.1\",\n        \"license\": \"CC0\"\n    }\n}\n"
  },
  {
    "path": "pyopenagi/agents/example/rag_agent/data/paul_graham/paul_graham_essay.txt",
    "content": "\n\nWhat I Worked On\n\nFebruary 2021\n\nBefore college the two main things I worked on, outside of school, were writing and programming. I didn't write essays. I wrote what beginning writers were supposed to write then, and probably still are: short stories. My stories were awful. They had hardly any plot, just characters with strong feelings, which I imagined made them deep.\n\nThe first programs I tried writing were on the IBM 1401 that our school district used for what was then called \"data processing.\" This was in 9th grade, so I was 13 or 14. The school district's 1401 happened to be in the basement of our junior high school, and my friend Rich Draves and I got permission to use it. It was like a mini Bond villain's lair down there, with all these alien-looking machines — CPU, disk drives, printer, card reader — sitting up on a raised floor under bright fluorescent lights.\n\nThe language we used was an early version of Fortran. You had to type programs on punch cards, then stack them in the card reader and press a button to load the program into memory and run it. The result would ordinarily be to print something on the spectacularly loud printer.\n\nI was puzzled by the 1401. I couldn't figure out what to do with it. And in retrospect there's not much I could have done with it. The only form of input to programs was data stored on punched cards, and I didn't have any data stored on punched cards. The only other option was to do things that didn't rely on any input, like calculate approximations of pi, but I didn't know enough math to do anything interesting of that type. So I'm not surprised I can't remember any programs I wrote, because they can't have done much. My clearest memory is of the moment I learned it was possible for programs not to terminate, when one of mine didn't. On a machine without time-sharing, this was a social as well as a technical error, as the data center manager's expression made clear.\n\nWith microcomputers, everything changed. Now you could have a computer sitting right in front of you, on a desk, that could respond to your keystrokes as it was running instead of just churning through a stack of punch cards and then stopping. [1]\n\nThe first of my friends to get a microcomputer built it himself. It was sold as a kit by Heathkit. I remember vividly how impressed and envious I felt watching him sitting in front of it, typing programs right into the computer.\n\nComputers were expensive in those days and it took me years of nagging before I convinced my father to buy one, a TRS-80, in about 1980. The gold standard then was the Apple II, but a TRS-80 was good enough. This was when I really started programming. I wrote simple games, a program to predict how high my model rockets would fly, and a word processor that my father used to write at least one book. There was only room in memory for about 2 pages of text, so he'd write 2 pages at a time and then print them out, but it was a lot better than a typewriter.\n\nThough I liked programming, I didn't plan to study it in college. In college I was going to study philosophy, which sounded much more powerful. It seemed, to my naive high school self, to be the study of the ultimate truths, compared to which the things studied in other fields would be mere domain knowledge. What I discovered when I got to college was that the other fields took up so much of the space of ideas that there wasn't much left for these supposed ultimate truths. All that seemed left for philosophy were edge cases that people in other fields felt could safely be ignored.\n\nI couldn't have put this into words when I was 18. All I knew at the time was that I kept taking philosophy courses and they kept being boring. So I decided to switch to AI.\n\nAI was in the air in the mid 1980s, but there were two things especially that made me want to work on it: a novel by Heinlein called The Moon is a Harsh Mistress, which featured an intelligent computer called Mike, and a PBS documentary that showed Terry Winograd using SHRDLU. I haven't tried rereading The Moon is a Harsh Mistress, so I don't know how well it has aged, but when I read it I was drawn entirely into its world. It seemed only a matter of time before we'd have Mike, and when I saw Winograd using SHRDLU, it seemed like that time would be a few years at most. All you had to do was teach SHRDLU more words.\n\nThere weren't any classes in AI at Cornell then, not even graduate classes, so I started trying to teach myself. Which meant learning Lisp, since in those days Lisp was regarded as the language of AI. The commonly used programming languages then were pretty primitive, and programmers' ideas correspondingly so. The default language at Cornell was a Pascal-like language called PL/I, and the situation was similar elsewhere. Learning Lisp expanded my concept of a program so fast that it was years before I started to have a sense of where the new limits were. This was more like it; this was what I had expected college to do. It wasn't happening in a class, like it was supposed to, but that was ok. For the next couple years I was on a roll. I knew what I was going to do.\n\nFor my undergraduate thesis, I reverse-engineered SHRDLU. My God did I love working on that program. It was a pleasing bit of code, but what made it even more exciting was my belief — hard to imagine now, but not unique in 1985 — that it was already climbing the lower slopes of intelligence.\n\nI had gotten into a program at Cornell that didn't make you choose a major. You could take whatever classes you liked, and choose whatever you liked to put on your degree. I of course chose \"Artificial Intelligence.\" When I got the actual physical diploma, I was dismayed to find that the quotes had been included, which made them read as scare-quotes. At the time this bothered me, but now it seems amusingly accurate, for reasons I was about to discover.\n\nI applied to 3 grad schools: MIT and Yale, which were renowned for AI at the time, and Harvard, which I'd visited because Rich Draves went there, and was also home to Bill Woods, who'd invented the type of parser I used in my SHRDLU clone. Only Harvard accepted me, so that was where I went.\n\nI don't remember the moment it happened, or if there even was a specific moment, but during the first year of grad school I realized that AI, as practiced at the time, was a hoax. By which I mean the sort of AI in which a program that's told \"the dog is sitting on the chair\" translates this into some formal representation and adds it to the list of things it knows.\n\nWhat these programs really showed was that there's a subset of natural language that's a formal language. But a very proper subset. It was clear that there was an unbridgeable gap between what they could do and actually understanding natural language. It was not, in fact, simply a matter of teaching SHRDLU more words. That whole way of doing AI, with explicit data structures representing concepts, was not going to work. Its brokenness did, as so often happens, generate a lot of opportunities to write papers about various band-aids that could be applied to it, but it was never going to get us Mike.\n\nSo I looked around to see what I could salvage from the wreckage of my plans, and there was Lisp. I knew from experience that Lisp was interesting for its own sake and not just for its association with AI, even though that was the main reason people cared about it at the time. So I decided to focus on Lisp. In fact, I decided to write a book about Lisp hacking. It's scary to think how little I knew about Lisp hacking when I started writing that book. But there's nothing like writing a book about something to help you learn it. The book, On Lisp, wasn't published till 1993, but I wrote much of it in grad school.\n\nComputer Science is an uneasy alliance between two halves, theory and systems. The theory people prove things, and the systems people build things. I wanted to build things. I had plenty of respect for theory — indeed, a sneaking suspicion that it was the more admirable of the two halves — but building things seemed so much more exciting.\n\nThe problem with systems work, though, was that it didn't last. Any program you wrote today, no matter how good, would be obsolete in a couple decades at best. People might mention your software in footnotes, but no one would actually use it. And indeed, it would seem very feeble work. Only people with a sense of the history of the field would even realize that, in its time, it had been good.\n\nThere were some surplus Xerox Dandelions floating around the computer lab at one point. Anyone who wanted one to play around with could have one. I was briefly tempted, but they were so slow by present standards; what was the point? No one else wanted one either, so off they went. That was what happened to systems work.\n\nI wanted not just to build things, but to build things that would last.\n\nIn this dissatisfied state I went in 1988 to visit Rich Draves at CMU, where he was in grad school. One day I went to visit the Carnegie Institute, where I'd spent a lot of time as a kid. While looking at a painting there I realized something that might seem obvious, but was a big surprise to me. There, right on the wall, was something you could make that would last. Paintings didn't become obsolete. Some of the best ones were hundreds of years old.\n\nAnd moreover this was something you could make a living doing. Not as easily as you could by writing software, of course, but I thought if you were really industrious and lived really cheaply, it had to be possible to make enough to survive. And as an artist you could be truly independent. You wouldn't have a boss, or even need to get research funding.\n\nI had always liked looking at paintings. Could I make them? I had no idea. I'd never imagined it was even possible. I knew intellectually that people made art — that it didn't just appear spontaneously — but it was as if the people who made it were a different species. They either lived long ago or were mysterious geniuses doing strange things in profiles in Life magazine. The idea of actually being able to make art, to put that verb before that noun, seemed almost miraculous.\n\nThat fall I started taking art classes at Harvard. Grad students could take classes in any department, and my advisor, Tom Cheatham, was very easy going. If he even knew about the strange classes I was taking, he never said anything.\n\nSo now I was in a PhD program in computer science, yet planning to be an artist, yet also genuinely in love with Lisp hacking and working away at On Lisp. In other words, like many a grad student, I was working energetically on multiple projects that were not my thesis.\n\nI didn't see a way out of this situation. I didn't want to drop out of grad school, but how else was I going to get out? I remember when my friend Robert Morris got kicked out of Cornell for writing the internet worm of 1988, I was envious that he'd found such a spectacular way to get out of grad school.\n\nThen one day in April 1990 a crack appeared in the wall. I ran into professor Cheatham and he asked if I was far enough along to graduate that June. I didn't have a word of my dissertation written, but in what must have been the quickest bit of thinking in my life, I decided to take a shot at writing one in the 5 weeks or so that remained before the deadline, reusing parts of On Lisp where I could, and I was able to respond, with no perceptible delay \"Yes, I think so. I'll give you something to read in a few days.\"\n\nI picked applications of continuations as the topic. In retrospect I should have written about macros and embedded languages. There's a whole world there that's barely been explored. But all I wanted was to get out of grad school, and my rapidly written dissertation sufficed, just barely.\n\nMeanwhile I was applying to art schools. I applied to two: RISD in the US, and the Accademia di Belli Arti in Florence, which, because it was the oldest art school, I imagined would be good. RISD accepted me, and I never heard back from the Accademia, so off to Providence I went.\n\nI'd applied for the BFA program at RISD, which meant in effect that I had to go to college again. This was not as strange as it sounds, because I was only 25, and art schools are full of people of different ages. RISD counted me as a transfer sophomore and said I had to do the foundation that summer. The foundation means the classes that everyone has to take in fundamental subjects like drawing, color, and design.\n\nToward the end of the summer I got a big surprise: a letter from the Accademia, which had been delayed because they'd sent it to Cambridge England instead of Cambridge Massachusetts, inviting me to take the entrance exam in Florence that fall. This was now only weeks away. My nice landlady let me leave my stuff in her attic. I had some money saved from consulting work I'd done in grad school; there was probably enough to last a year if I lived cheaply. Now all I had to do was learn Italian.\n\nOnly stranieri (foreigners) had to take this entrance exam. In retrospect it may well have been a way of excluding them, because there were so many stranieri attracted by the idea of studying art in Florence that the Italian students would otherwise have been outnumbered. I was in decent shape at painting and drawing from the RISD foundation that summer, but I still don't know how I managed to pass the written exam. I remember that I answered the essay question by writing about Cezanne, and that I cranked up the intellectual level as high as I could to make the most of my limited vocabulary. [2]\n\nI'm only up to age 25 and already there are such conspicuous patterns. Here I was, yet again about to attend some august institution in the hopes of learning about some prestigious subject, and yet again about to be disappointed. The students and faculty in the painting department at the Accademia were the nicest people you could imagine, but they had long since arrived at an arrangement whereby the students wouldn't require the faculty to teach anything, and in return the faculty wouldn't require the students to learn anything. And at the same time all involved would adhere outwardly to the conventions of a 19th century atelier. We actually had one of those little stoves, fed with kindling, that you see in 19th century studio paintings, and a nude model sitting as close to it as possible without getting burned. Except hardly anyone else painted her besides me. The rest of the students spent their time chatting or occasionally trying to imitate things they'd seen in American art magazines.\n\nOur model turned out to live just down the street from me. She made a living from a combination of modelling and making fakes for a local antique dealer. She'd copy an obscure old painting out of a book, and then he'd take the copy and maltreat it to make it look old. [3]\n\nWhile I was a student at the Accademia I started painting still lives in my bedroom at night. These paintings were tiny, because the room was, and because I painted them on leftover scraps of canvas, which was all I could afford at the time. Painting still lives is different from painting people, because the subject, as its name suggests, can't move. People can't sit for more than about 15 minutes at a time, and when they do they don't sit very still. So the traditional m.o. for painting people is to know how to paint a generic person, which you then modify to match the specific person you're painting. Whereas a still life you can, if you want, copy pixel by pixel from what you're seeing. You don't want to stop there, of course, or you get merely photographic accuracy, and what makes a still life interesting is that it's been through a head. You want to emphasize the visual cues that tell you, for example, that the reason the color changes suddenly at a certain point is that it's the edge of an object. By subtly emphasizing such things you can make paintings that are more realistic than photographs not just in some metaphorical sense, but in the strict information-theoretic sense. [4]\n\nI liked painting still lives because I was curious about what I was seeing. In everyday life, we aren't consciously aware of much we're seeing. Most visual perception is handled by low-level processes that merely tell your brain \"that's a water droplet\" without telling you details like where the lightest and darkest points are, or \"that's a bush\" without telling you the shape and position of every leaf. This is a feature of brains, not a bug. In everyday life it would be distracting to notice every leaf on every bush. But when you have to paint something, you have to look more closely, and when you do there's a lot to see. You can still be noticing new things after days of trying to paint something people usually take for granted, just as you can after days of trying to write an essay about something people usually take for granted.\n\nThis is not the only way to paint. I'm not 100% sure it's even a good way to paint. But it seemed a good enough bet to be worth trying.\n\nOur teacher, professor Ulivi, was a nice guy. He could see I worked hard, and gave me a good grade, which he wrote down in a sort of passport each student had. But the Accademia wasn't teaching me anything except Italian, and my money was running out, so at the end of the first year I went back to the US.\n\nI wanted to go back to RISD, but I was now broke and RISD was very expensive, so I decided to get a job for a year and then return to RISD the next fall. I got one at a company called Interleaf, which made software for creating documents. You mean like Microsoft Word? Exactly. That was how I learned that low end software tends to eat high end software. But Interleaf still had a few years to live yet. [5]\n\nInterleaf had done something pretty bold. Inspired by Emacs, they'd added a scripting language, and even made the scripting language a dialect of Lisp. Now they wanted a Lisp hacker to write things in it. This was the closest thing I've had to a normal job, and I hereby apologize to my boss and coworkers, because I was a bad employee. Their Lisp was the thinnest icing on a giant C cake, and since I didn't know C and didn't want to learn it, I never understood most of the software. Plus I was terribly irresponsible. This was back when a programming job meant showing up every day during certain working hours. That seemed unnatural to me, and on this point the rest of the world is coming around to my way of thinking, but at the time it caused a lot of friction. Toward the end of the year I spent much of my time surreptitiously working on On Lisp, which I had by this time gotten a contract to publish.\n\nThe good part was that I got paid huge amounts of money, especially by art student standards. In Florence, after paying my part of the rent, my budget for everything else had been $7 a day. Now I was getting paid more than 4 times that every hour, even when I was just sitting in a meeting. By living cheaply I not only managed to save enough to go back to RISD, but also paid off my college loans.\n\nI learned some useful things at Interleaf, though they were mostly about what not to do. I learned that it's better for technology companies to be run by product people than sales people (though sales is a real skill and people who are good at it are really good at it), that it leads to bugs when code is edited by too many people, that cheap office space is no bargain if it's depressing, that planned meetings are inferior to corridor conversations, that big, bureaucratic customers are a dangerous source of money, and that there's not much overlap between conventional office hours and the optimal time for hacking, or conventional offices and the optimal place for it.\n\nBut the most important thing I learned, and which I used in both Viaweb and Y Combinator, is that the low end eats the high end: that it's good to be the \"entry level\" option, even though that will be less prestigious, because if you're not, someone else will be, and will squash you against the ceiling. Which in turn means that prestige is a danger sign.\n\nWhen I left to go back to RISD the next fall, I arranged to do freelance work for the group that did projects for customers, and this was how I survived for the next several years. When I came back to visit for a project later on, someone told me about a new thing called HTML, which was, as he described it, a derivative of SGML. Markup language enthusiasts were an occupational hazard at Interleaf and I ignored him, but this HTML thing later became a big part of my life.\n\nIn the fall of 1992 I moved back to Providence to continue at RISD. The foundation had merely been intro stuff, and the Accademia had been a (very civilized) joke. Now I was going to see what real art school was like. But alas it was more like the Accademia than not. Better organized, certainly, and a lot more expensive, but it was now becoming clear that art school did not bear the same relationship to art that medical school bore to medicine. At least not the painting department. The textile department, which my next door neighbor belonged to, seemed to be pretty rigorous. No doubt illustration and architecture were too. But painting was post-rigorous. Painting students were supposed to express themselves, which to the more worldly ones meant to try to cook up some sort of distinctive signature style.\n\nA signature style is the visual equivalent of what in show business is known as a \"schtick\": something that immediately identifies the work as yours and no one else's. For example, when you see a painting that looks like a certain kind of cartoon, you know it's by Roy Lichtenstein. So if you see a big painting of this type hanging in the apartment of a hedge fund manager, you know he paid millions of dollars for it. That's not always why artists have a signature style, but it's usually why buyers pay a lot for such work. [6]\n\nThere were plenty of earnest students too: kids who \"could draw\" in high school, and now had come to what was supposed to be the best art school in the country, to learn to draw even better. They tended to be confused and demoralized by what they found at RISD, but they kept going, because painting was what they did. I was not one of the kids who could draw in high school, but at RISD I was definitely closer to their tribe than the tribe of signature style seekers.\n\nI learned a lot in the color class I took at RISD, but otherwise I was basically teaching myself to paint, and I could do that for free. So in 1993 I dropped out. I hung around Providence for a bit, and then my college friend Nancy Parmet did me a big favor. A rent-controlled apartment in a building her mother owned in New York was becoming vacant. Did I want it? It wasn't much more than my current place, and New York was supposed to be where the artists were. So yes, I wanted it! [7]\n\nAsterix comics begin by zooming in on a tiny corner of Roman Gaul that turns out not to be controlled by the Romans. You can do something similar on a map of New York City: if you zoom in on the Upper East Side, there's a tiny corner that's not rich, or at least wasn't in 1993. It's called Yorkville, and that was my new home. Now I was a New York artist — in the strictly technical sense of making paintings and living in New York.\n\nI was nervous about money, because I could sense that Interleaf was on the way down. Freelance Lisp hacking work was very rare, and I didn't want to have to program in another language, which in those days would have meant C++ if I was lucky. So with my unerring nose for financial opportunity, I decided to write another book on Lisp. This would be a popular book, the sort of book that could be used as a textbook. I imagined myself living frugally off the royalties and spending all my time painting. (The painting on the cover of this book, ANSI Common Lisp, is one that I painted around this time.)\n\nThe best thing about New York for me was the presence of Idelle and Julian Weber. Idelle Weber was a painter, one of the early photorealists, and I'd taken her painting class at Harvard. I've never known a teacher more beloved by her students. Large numbers of former students kept in touch with her, including me. After I moved to New York I became her de facto studio assistant.\n\nShe liked to paint on big, square canvases, 4 to 5 feet on a side. One day in late 1994 as I was stretching one of these monsters there was something on the radio about a famous fund manager. He wasn't that much older than me, and was super rich. The thought suddenly occurred to me: why don't I become rich? Then I'll be able to work on whatever I want.\n\nMeanwhile I'd been hearing more and more about this new thing called the World Wide Web. Robert Morris showed it to me when I visited him in Cambridge, where he was now in grad school at Harvard. It seemed to me that the web would be a big deal. I'd seen what graphical user interfaces had done for the popularity of microcomputers. It seemed like the web would do the same for the internet.\n\nIf I wanted to get rich, here was the next train leaving the station. I was right about that part. What I got wrong was the idea. I decided we should start a company to put art galleries online. I can't honestly say, after reading so many Y Combinator applications, that this was the worst startup idea ever, but it was up there. Art galleries didn't want to be online, and still don't, not the fancy ones. That's not how they sell. I wrote some software to generate web sites for galleries, and Robert wrote some to resize images and set up an http server to serve the pages. Then we tried to sign up galleries. To call this a difficult sale would be an understatement. It was difficult to give away. A few galleries let us make sites for them for free, but none paid us.\n\nThen some online stores started to appear, and I realized that except for the order buttons they were identical to the sites we'd been generating for galleries. This impressive-sounding thing called an \"internet storefront\" was something we already knew how to build.\n\nSo in the summer of 1995, after I submitted the camera-ready copy of ANSI Common Lisp to the publishers, we started trying to write software to build online stores. At first this was going to be normal desktop software, which in those days meant Windows software. That was an alarming prospect, because neither of us knew how to write Windows software or wanted to learn. We lived in the Unix world. But we decided we'd at least try writing a prototype store builder on Unix. Robert wrote a shopping cart, and I wrote a new site generator for stores — in Lisp, of course.\n\nWe were working out of Robert's apartment in Cambridge. His roommate was away for big chunks of time, during which I got to sleep in his room. For some reason there was no bed frame or sheets, just a mattress on the floor. One morning as I was lying on this mattress I had an idea that made me sit up like a capital L. What if we ran the software on the server, and let users control it by clicking on links? Then we'd never have to write anything to run on users' computers. We could generate the sites on the same server we'd serve them from. Users wouldn't need anything more than a browser.\n\nThis kind of software, known as a web app, is common now, but at the time it wasn't clear that it was even possible. To find out, we decided to try making a version of our store builder that you could control through the browser. A couple days later, on August 12, we had one that worked. The UI was horrible, but it proved you could build a whole store through the browser, without any client software or typing anything into the command line on the server.\n\nNow we felt like we were really onto something. I had visions of a whole new generation of software working this way. You wouldn't need versions, or ports, or any of that crap. At Interleaf there had been a whole group called Release Engineering that seemed to be at least as big as the group that actually wrote the software. Now you could just update the software right on the server.\n\nWe started a new company we called Viaweb, after the fact that our software worked via the web, and we got $10,000 in seed funding from Idelle's husband Julian. In return for that and doing the initial legal work and giving us business advice, we gave him 10% of the company. Ten years later this deal became the model for Y Combinator's. We knew founders needed something like this, because we'd needed it ourselves.\n\nAt this stage I had a negative net worth, because the thousand dollars or so I had in the bank was more than counterbalanced by what I owed the government in taxes. (Had I diligently set aside the proper proportion of the money I'd made consulting for Interleaf? No, I had not.) So although Robert had his graduate student stipend, I needed that seed funding to live on.\n\nWe originally hoped to launch in September, but we got more ambitious about the software as we worked on it. Eventually we managed to build a WYSIWYG site builder, in the sense that as you were creating pages, they looked exactly like the static ones that would be generated later, except that instead of leading to static pages, the links all referred to closures stored in a hash table on the server.\n\nIt helped to have studied art, because the main goal of an online store builder is to make users look legit, and the key to looking legit is high production values. If you get page layouts and fonts and colors right, you can make a guy running a store out of his bedroom look more legit than a big company.\n\n(If you're curious why my site looks so old-fashioned, it's because it's still made with this software. It may look clunky today, but in 1996 it was the last word in slick.)\n\nIn September, Robert rebelled. \"We've been working on this for a month,\" he said, \"and it's still not done.\" This is funny in retrospect, because he would still be working on it almost 3 years later. But I decided it might be prudent to recruit more programmers, and I asked Robert who else in grad school with him was really good. He recommended Trevor Blackwell, which surprised me at first, because at that point I knew Trevor mainly for his plan to reduce everything in his life to a stack of notecards, which he carried around with him. But Rtm was right, as usual. Trevor turned out to be a frighteningly effective hacker.\n\nIt was a lot of fun working with Robert and Trevor. They're the two most independent-minded people I know, and in completely different ways. If you could see inside Rtm's brain it would look like a colonial New England church, and if you could see inside Trevor's it would look like the worst excesses of Austrian Rococo.\n\nWe opened for business, with 6 stores, in January 1996. It was just as well we waited a few months, because although we worried we were late, we were actually almost fatally early. There was a lot of talk in the press then about ecommerce, but not many people actually wanted online stores. [8]\n\nThere were three main parts to the software: the editor, which people used to build sites and which I wrote, the shopping cart, which Robert wrote, and the manager, which kept track of orders and statistics, and which Trevor wrote. In its time, the editor was one of the best general-purpose site builders. I kept the code tight and didn't have to integrate with any other software except Robert's and Trevor's, so it was quite fun to work on. If all I'd had to do was work on this software, the next 3 years would have been the easiest of my life. Unfortunately I had to do a lot more, all of it stuff I was worse at than programming, and the next 3 years were instead the most stressful.\n\nThere were a lot of startups making ecommerce software in the second half of the 90s. We were determined to be the Microsoft Word, not the Interleaf. Which meant being easy to use and inexpensive. It was lucky for us that we were poor, because that caused us to make Viaweb even more inexpensive than we realized. We charged $100 a month for a small store and $300 a month for a big one. This low price was a big attraction, and a constant thorn in the sides of competitors, but it wasn't because of some clever insight that we set the price low. We had no idea what businesses paid for things. $300 a month seemed like a lot of money to us.\n\nWe did a lot of things right by accident like that. For example, we did what's now called \"doing things that don't scale,\" although at the time we would have described it as \"being so lame that we're driven to the most desperate measures to get users.\" The most common of which was building stores for them. This seemed particularly humiliating, since the whole raison d'etre of our software was that people could use it to make their own stores. But anything to get users.\n\nWe learned a lot more about retail than we wanted to know. For example, that if you could only have a small image of a man's shirt (and all images were small then by present standards), it was better to have a closeup of the collar than a picture of the whole shirt. The reason I remember learning this was that it meant I had to rescan about 30 images of men's shirts. My first set of scans were so beautiful too.\n\nThough this felt wrong, it was exactly the right thing to be doing. Building stores for users taught us about retail, and about how it felt to use our software. I was initially both mystified and repelled by \"business\" and thought we needed a \"business person\" to be in charge of it, but once we started to get users, I was converted, in much the same way I was converted to fatherhood once I had kids. Whatever users wanted, I was all theirs. Maybe one day we'd have so many users that I couldn't scan their images for them, but in the meantime there was nothing more important to do.\n\nAnother thing I didn't get at the time is that growth rate is the ultimate test of a startup. Our growth rate was fine. We had about 70 stores at the end of 1996 and about 500 at the end of 1997. I mistakenly thought the thing that mattered was the absolute number of users. And that is the thing that matters in the sense that that's how much money you're making, and if you're not making enough, you might go out of business. But in the long term the growth rate takes care of the absolute number. If we'd been a startup I was advising at Y Combinator, I would have said: Stop being so stressed out, because you're doing fine. You're growing 7x a year. Just don't hire too many more people and you'll soon be profitable, and then you'll control your own destiny.\n\nAlas I hired lots more people, partly because our investors wanted me to, and partly because that's what startups did during the Internet Bubble. A company with just a handful of employees would have seemed amateurish. So we didn't reach breakeven until about when Yahoo bought us in the summer of 1998. Which in turn meant we were at the mercy of investors for the entire life of the company. And since both we and our investors were noobs at startups, the result was a mess even by startup standards.\n\nIt was a huge relief when Yahoo bought us. In principle our Viaweb stock was valuable. It was a share in a business that was profitable and growing rapidly. But it didn't feel very valuable to me; I had no idea how to value a business, but I was all too keenly aware of the near-death experiences we seemed to have every few months. Nor had I changed my grad student lifestyle significantly since we started. So when Yahoo bought us it felt like going from rags to riches. Since we were going to California, I bought a car, a yellow 1998 VW GTI. I remember thinking that its leather seats alone were by far the most luxurious thing I owned.\n\nThe next year, from the summer of 1998 to the summer of 1999, must have been the least productive of my life. I didn't realize it at the time, but I was worn out from the effort and stress of running Viaweb. For a while after I got to California I tried to continue my usual m.o. of programming till 3 in the morning, but fatigue combined with Yahoo's prematurely aged culture and grim cube farm in Santa Clara gradually dragged me down. After a few months it felt disconcertingly like working at Interleaf.\n\nYahoo had given us a lot of options when they bought us. At the time I thought Yahoo was so overvalued that they'd never be worth anything, but to my astonishment the stock went up 5x in the next year. I hung on till the first chunk of options vested, then in the summer of 1999 I left. It had been so long since I'd painted anything that I'd half forgotten why I was doing this. My brain had been entirely full of software and men's shirts for 4 years. But I had done this to get rich so I could paint, I reminded myself, and now I was rich, so I should go paint.\n\nWhen I said I was leaving, my boss at Yahoo had a long conversation with me about my plans. I told him all about the kinds of pictures I wanted to paint. At the time I was touched that he took such an interest in me. Now I realize it was because he thought I was lying. My options at that point were worth about $2 million a month. If I was leaving that kind of money on the table, it could only be to go and start some new startup, and if I did, I might take people with me. This was the height of the Internet Bubble, and Yahoo was ground zero of it. My boss was at that moment a billionaire. Leaving then to start a new startup must have seemed to him an insanely, and yet also plausibly, ambitious plan.\n\nBut I really was quitting to paint, and I started immediately. There was no time to lose. I'd already burned 4 years getting rich. Now when I talk to founders who are leaving after selling their companies, my advice is always the same: take a vacation. That's what I should have done, just gone off somewhere and done nothing for a month or two, but the idea never occurred to me.\n\nSo I tried to paint, but I just didn't seem to have any energy or ambition. Part of the problem was that I didn't know many people in California. I'd compounded this problem by buying a house up in the Santa Cruz Mountains, with a beautiful view but miles from anywhere. I stuck it out for a few more months, then in desperation I went back to New York, where unless you understand about rent control you'll be surprised to hear I still had my apartment, sealed up like a tomb of my old life. Idelle was in New York at least, and there were other people trying to paint there, even though I didn't know any of them.\n\nWhen I got back to New York I resumed my old life, except now I was rich. It was as weird as it sounds. I resumed all my old patterns, except now there were doors where there hadn't been. Now when I was tired of walking, all I had to do was raise my hand, and (unless it was raining) a taxi would stop to pick me up. Now when I walked past charming little restaurants I could go in and order lunch. It was exciting for a while. Painting started to go better. I experimented with a new kind of still life where I'd paint one painting in the old way, then photograph it and print it, blown up, on canvas, and then use that as the underpainting for a second still life, painted from the same objects (which hopefully hadn't rotted yet).\n\nMeanwhile I looked for an apartment to buy. Now I could actually choose what neighborhood to live in. Where, I asked myself and various real estate agents, is the Cambridge of New York? Aided by occasional visits to actual Cambridge, I gradually realized there wasn't one. Huh.\n\nAround this time, in the spring of 2000, I had an idea. It was clear from our experience with Viaweb that web apps were the future. Why not build a web app for making web apps? Why not let people edit code on our server through the browser, and then host the resulting applications for them? [9] You could run all sorts of services on the servers that these applications could use just by making an API call: making and receiving phone calls, manipulating images, taking credit card payments, etc.\n\nI got so excited about this idea that I couldn't think about anything else. It seemed obvious that this was the future. I didn't particularly want to start another company, but it was clear that this idea would have to be embodied as one, so I decided to move to Cambridge and start it. I hoped to lure Robert into working on it with me, but there I ran into a hitch. Robert was now a postdoc at MIT, and though he'd made a lot of money the last time I'd lured him into working on one of my schemes, it had also been a huge time sink. So while he agreed that it sounded like a plausible idea, he firmly refused to work on it.\n\nHmph. Well, I'd do it myself then. I recruited Dan Giffin, who had worked for Viaweb, and two undergrads who wanted summer jobs, and we got to work trying to build what it's now clear is about twenty companies and several open source projects worth of software. The language for defining applications would of course be a dialect of Lisp. But I wasn't so naive as to assume I could spring an overt Lisp on a general audience; we'd hide the parentheses, like Dylan did.\n\nBy then there was a name for the kind of company Viaweb was, an \"application service provider,\" or ASP. This name didn't last long before it was replaced by \"software as a service,\" but it was current for long enough that I named this new company after it: it was going to be called Aspra.\n\nI started working on the application builder, Dan worked on network infrastructure, and the two undergrads worked on the first two services (images and phone calls). But about halfway through the summer I realized I really didn't want to run a company — especially not a big one, which it was looking like this would have to be. I'd only started Viaweb because I needed the money. Now that I didn't need money anymore, why was I doing this? If this vision had to be realized as a company, then screw the vision. I'd build a subset that could be done as an open source project.\n\nMuch to my surprise, the time I spent working on this stuff was not wasted after all. After we started Y Combinator, I would often encounter startups working on parts of this new architecture, and it was very useful to have spent so much time thinking about it and even trying to write some of it.\n\nThe subset I would build as an open source project was the new Lisp, whose parentheses I now wouldn't even have to hide. A lot of Lisp hackers dream of building a new Lisp, partly because one of the distinctive features of the language is that it has dialects, and partly, I think, because we have in our minds a Platonic form of Lisp that all existing dialects fall short of. I certainly did. So at the end of the summer Dan and I switched to working on this new dialect of Lisp, which I called Arc, in a house I bought in Cambridge.\n\nThe following spring, lightning struck. I was invited to give a talk at a Lisp conference, so I gave one about how we'd used Lisp at Viaweb. Afterward I put a postscript file of this talk online, on paulgraham.com, which I'd created years before using Viaweb but had never used for anything. In one day it got 30,000 page views. What on earth had happened? The referring urls showed that someone had posted it on Slashdot. [10]\n\nWow, I thought, there's an audience. If I write something and put it on the web, anyone can read it. That may seem obvious now, but it was surprising then. In the print era there was a narrow channel to readers, guarded by fierce monsters known as editors. The only way to get an audience for anything you wrote was to get it published as a book, or in a newspaper or magazine. Now anyone could publish anything.\n\nThis had been possible in principle since 1993, but not many people had realized it yet. I had been intimately involved with building the infrastructure of the web for most of that time, and a writer as well, and it had taken me 8 years to realize it. Even then it took me several years to understand the implications. It meant there would be a whole new generation of essays. [11]\n\nIn the print era, the channel for publishing essays had been vanishingly small. Except for a few officially anointed thinkers who went to the right parties in New York, the only people allowed to publish essays were specialists writing about their specialties. There were so many essays that had never been written, because there had been no way to publish them. Now they could be, and I was going to write them. [12]\n\nI've worked on several different things, but to the extent there was a turning point where I figured out what to work on, it was when I started publishing essays online. From then on I knew that whatever else I did, I'd always write essays too.\n\nI knew that online essays would be a marginal medium at first. Socially they'd seem more like rants posted by nutjobs on their GeoCities sites than the genteel and beautifully typeset compositions published in The New Yorker. But by this point I knew enough to find that encouraging instead of discouraging.\n\nOne of the most conspicuous patterns I've noticed in my life is how well it has worked, for me at least, to work on things that weren't prestigious. Still life has always been the least prestigious form of painting. Viaweb and Y Combinator both seemed lame when we started them. I still get the glassy eye from strangers when they ask what I'm writing, and I explain that it's an essay I'm going to publish on my web site. Even Lisp, though prestigious intellectually in something like the way Latin is, also seems about as hip.\n\nIt's not that unprestigious types of work are good per se. But when you find yourself drawn to some kind of work despite its current lack of prestige, it's a sign both that there's something real to be discovered there, and that you have the right kind of motives. Impure motives are a big danger for the ambitious. If anything is going to lead you astray, it will be the desire to impress people. So while working on things that aren't prestigious doesn't guarantee you're on the right track, it at least guarantees you're not on the most common type of wrong one.\n\nOver the next several years I wrote lots of essays about all kinds of different topics. O'Reilly reprinted a collection of them as a book, called Hackers & Painters after one of the essays in it. I also worked on spam filters, and did some more painting. I used to have dinners for a group of friends every thursday night, which taught me how to cook for groups. And I bought another building in Cambridge, a former candy factory (and later, twas said, porn studio), to use as an office.\n\nOne night in October 2003 there was a big party at my house. It was a clever idea of my friend Maria Daniels, who was one of the thursday diners. Three separate hosts would all invite their friends to one party. So for every guest, two thirds of the other guests would be people they didn't know but would probably like. One of the guests was someone I didn't know but would turn out to like a lot: a woman called Jessica Livingston. A couple days later I asked her out.\n\nJessica was in charge of marketing at a Boston investment bank. This bank thought it understood startups, but over the next year, as she met friends of mine from the startup world, she was surprised how different reality was. And how colorful their stories were. So she decided to compile a book of interviews with startup founders.\n\nWhen the bank had financial problems and she had to fire half her staff, she started looking for a new job. In early 2005 she interviewed for a marketing job at a Boston VC firm. It took them weeks to make up their minds, and during this time I started telling her about all the things that needed to be fixed about venture capital. They should make a larger number of smaller investments instead of a handful of giant ones, they should be funding younger, more technical founders instead of MBAs, they should let the founders remain as CEO, and so on.\n\nOne of my tricks for writing essays had always been to give talks. The prospect of having to stand up in front of a group of people and tell them something that won't waste their time is a great spur to the imagination. When the Harvard Computer Society, the undergrad computer club, asked me to give a talk, I decided I would tell them how to start a startup. Maybe they'd be able to avoid the worst of the mistakes we'd made.\n\nSo I gave this talk, in the course of which I told them that the best sources of seed funding were successful startup founders, because then they'd be sources of advice too. Whereupon it seemed they were all looking expectantly at me. Horrified at the prospect of having my inbox flooded by business plans (if I'd only known), I blurted out \"But not me!\" and went on with the talk. But afterward it occurred to me that I should really stop procrastinating about angel investing. I'd been meaning to since Yahoo bought us, and now it was 7 years later and I still hadn't done one angel investment.\n\nMeanwhile I had been scheming with Robert and Trevor about projects we could work on together. I missed working with them, and it seemed like there had to be something we could collaborate on.\n\nAs Jessica and I were walking home from dinner on March 11, at the corner of Garden and Walker streets, these three threads converged. Screw the VCs who were taking so long to make up their minds. We'd start our own investment firm and actually implement the ideas we'd been talking about. I'd fund it, and Jessica could quit her job and work for it, and we'd get Robert and Trevor as partners too. [13]\n\nOnce again, ignorance worked in our favor. We had no idea how to be angel investors, and in Boston in 2005 there were no Ron Conways to learn from. So we just made what seemed like the obvious choices, and some of the things we did turned out to be novel.\n\nThere are multiple components to Y Combinator, and we didn't figure them all out at once. The part we got first was to be an angel firm. In those days, those two words didn't go together. There were VC firms, which were organized companies with people whose job it was to make investments, but they only did big, million dollar investments. And there were angels, who did smaller investments, but these were individuals who were usually focused on other things and made investments on the side. And neither of them helped founders enough in the beginning. We knew how helpless founders were in some respects, because we remembered how helpless we'd been. For example, one thing Julian had done for us that seemed to us like magic was to get us set up as a company. We were fine writing fairly difficult software, but actually getting incorporated, with bylaws and stock and all that stuff, how on earth did you do that? Our plan was not only to make seed investments, but to do for startups everything Julian had done for us.\n\nYC was not organized as a fund. It was cheap enough to run that we funded it with our own money. That went right by 99% of readers, but professional investors are thinking \"Wow, that means they got all the returns.\" But once again, this was not due to any particular insight on our part. We didn't know how VC firms were organized. It never occurred to us to try to raise a fund, and if it had, we wouldn't have known where to start. [14]\n\nThe most distinctive thing about YC is the batch model: to fund a bunch of startups all at once, twice a year, and then to spend three months focusing intensively on trying to help them. That part we discovered by accident, not merely implicitly but explicitly due to our ignorance about investing. We needed to get experience as investors. What better way, we thought, than to fund a whole bunch of startups at once? We knew undergrads got temporary jobs at tech companies during the summer. Why not organize a summer program where they'd start startups instead? We wouldn't feel guilty for being in a sense fake investors, because they would in a similar sense be fake founders. So while we probably wouldn't make much money out of it, we'd at least get to practice being investors on them, and they for their part would probably have a more interesting summer than they would working at Microsoft.\n\nWe'd use the building I owned in Cambridge as our headquarters. We'd all have dinner there once a week — on tuesdays, since I was already cooking for the thursday diners on thursdays — and after dinner we'd bring in experts on startups to give talks.\n\nWe knew undergrads were deciding then about summer jobs, so in a matter of days we cooked up something we called the Summer Founders Program, and I posted an announcement on my site, inviting undergrads to apply. I had never imagined that writing essays would be a way to get \"deal flow,\" as investors call it, but it turned out to be the perfect source. [15] We got 225 applications for the Summer Founders Program, and we were surprised to find that a lot of them were from people who'd already graduated, or were about to that spring. Already this SFP thing was starting to feel more serious than we'd intended.\n\nWe invited about 20 of the 225 groups to interview in person, and from those we picked 8 to fund. They were an impressive group. That first batch included reddit, Justin Kan and Emmett Shear, who went on to found Twitch, Aaron Swartz, who had already helped write the RSS spec and would a few years later become a martyr for open access, and Sam Altman, who would later become the second president of YC. I don't think it was entirely luck that the first batch was so good. You had to be pretty bold to sign up for a weird thing like the Summer Founders Program instead of a summer job at a legit place like Microsoft or Goldman Sachs.\n\nThe deal for startups was based on a combination of the deal we did with Julian ($10k for 10%) and what Robert said MIT grad students got for the summer ($6k). We invested $6k per founder, which in the typical two-founder case was $12k, in return for 6%. That had to be fair, because it was twice as good as the deal we ourselves had taken. Plus that first summer, which was really hot, Jessica brought the founders free air conditioners. [16]\n\nFairly quickly I realized that we had stumbled upon the way to scale startup funding. Funding startups in batches was more convenient for us, because it meant we could do things for a lot of startups at once, but being part of a batch was better for the startups too. It solved one of the biggest problems faced by founders: the isolation. Now you not only had colleagues, but colleagues who understood the problems you were facing and could tell you how they were solving them.\n\nAs YC grew, we started to notice other advantages of scale. The alumni became a tight community, dedicated to helping one another, and especially the current batch, whose shoes they remembered being in. We also noticed that the startups were becoming one another's customers. We used to refer jokingly to the \"YC GDP,\" but as YC grows this becomes less and less of a joke. Now lots of startups get their initial set of customers almost entirely from among their batchmates.\n\nI had not originally intended YC to be a full-time job. I was going to do three things: hack, write essays, and work on YC. As YC grew, and I grew more excited about it, it started to take up a lot more than a third of my attention. But for the first few years I was still able to work on other things.\n\nIn the summer of 2006, Robert and I started working on a new version of Arc. This one was reasonably fast, because it was compiled into Scheme. To test this new Arc, I wrote Hacker News in it. It was originally meant to be a news aggregator for startup founders and was called Startup News, but after a few months I got tired of reading about nothing but startups. Plus it wasn't startup founders we wanted to reach. It was future startup founders. So I changed the name to Hacker News and the topic to whatever engaged one's intellectual curiosity.\n\nHN was no doubt good for YC, but it was also by far the biggest source of stress for me. If all I'd had to do was select and help founders, life would have been so easy. And that implies that HN was a mistake. Surely the biggest source of stress in one's work should at least be something close to the core of the work. Whereas I was like someone who was in pain while running a marathon not from the exertion of running, but because I had a blister from an ill-fitting shoe. When I was dealing with some urgent problem during YC, there was about a 60% chance it had to do with HN, and a 40% chance it had do with everything else combined. [17]\n\nAs well as HN, I wrote all of YC's internal software in Arc. But while I continued to work a good deal in Arc, I gradually stopped working on Arc, partly because I didn't have time to, and partly because it was a lot less attractive to mess around with the language now that we had all this infrastructure depending on it. So now my three projects were reduced to two: writing essays and working on YC.\n\nYC was different from other kinds of work I've done. Instead of deciding for myself what to work on, the problems came to me. Every 6 months there was a new batch of startups, and their problems, whatever they were, became our problems. It was very engaging work, because their problems were quite varied, and the good founders were very effective. If you were trying to learn the most you could about startups in the shortest possible time, you couldn't have picked a better way to do it.\n\nThere were parts of the job I didn't like. Disputes between cofounders, figuring out when people were lying to us, fighting with people who maltreated the startups, and so on. But I worked hard even at the parts I didn't like. I was haunted by something Kevin Hale once said about companies: \"No one works harder than the boss.\" He meant it both descriptively and prescriptively, and it was the second part that scared me. I wanted YC to be good, so if how hard I worked set the upper bound on how hard everyone else worked, I'd better work very hard.\n\nOne day in 2010, when he was visiting California for interviews, Robert Morris did something astonishing: he offered me unsolicited advice. I can only remember him doing that once before. One day at Viaweb, when I was bent over double from a kidney stone, he suggested that it would be a good idea for him to take me to the hospital. That was what it took for Rtm to offer unsolicited advice. So I remember his exact words very clearly. \"You know,\" he said, \"you should make sure Y Combinator isn't the last cool thing you do.\"\n\nAt the time I didn't understand what he meant, but gradually it dawned on me that he was saying I should quit. This seemed strange advice, because YC was doing great. But if there was one thing rarer than Rtm offering advice, it was Rtm being wrong. So this set me thinking. It was true that on my current trajectory, YC would be the last thing I did, because it was only taking up more of my attention. It had already eaten Arc, and was in the process of eating essays too. Either YC was my life's work or I'd have to leave eventually. And it wasn't, so I would.\n\nIn the summer of 2012 my mother had a stroke, and the cause turned out to be a blood clot caused by colon cancer. The stroke destroyed her balance, and she was put in a nursing home, but she really wanted to get out of it and back to her house, and my sister and I were determined to help her do it. I used to fly up to Oregon to visit her regularly, and I had a lot of time to think on those flights. On one of them I realized I was ready to hand YC over to someone else.\n\nI asked Jessica if she wanted to be president, but she didn't, so we decided we'd try to recruit Sam Altman. We talked to Robert and Trevor and we agreed to make it a complete changing of the guard. Up till that point YC had been controlled by the original LLC we four had started. But we wanted YC to last for a long time, and to do that it couldn't be controlled by the founders. So if Sam said yes, we'd let him reorganize YC. Robert and I would retire, and Jessica and Trevor would become ordinary partners.\n\nWhen we asked Sam if he wanted to be president of YC, initially he said no. He wanted to start a startup to make nuclear reactors. But I kept at it, and in October 2013 he finally agreed. We decided he'd take over starting with the winter 2014 batch. For the rest of 2013 I left running YC more and more to Sam, partly so he could learn the job, and partly because I was focused on my mother, whose cancer had returned.\n\nShe died on January 15, 2014. We knew this was coming, but it was still hard when it did.\n\nI kept working on YC till March, to help get that batch of startups through Demo Day, then I checked out pretty completely. (I still talk to alumni and to new startups working on things I'm interested in, but that only takes a few hours a week.)\n\nWhat should I do next? Rtm's advice hadn't included anything about that. I wanted to do something completely different, so I decided I'd paint. I wanted to see how good I could get if I really focused on it. So the day after I stopped working on YC, I started painting. I was rusty and it took a while to get back into shape, but it was at least completely engaging. [18]\n\nI spent most of the rest of 2014 painting. I'd never been able to work so uninterruptedly before, and I got to be better than I had been. Not good enough, but better. Then in November, right in the middle of a painting, I ran out of steam. Up till that point I'd always been curious to see how the painting I was working on would turn out, but suddenly finishing this one seemed like a chore. So I stopped working on it and cleaned my brushes and haven't painted since. So far anyway.\n\nI realize that sounds rather wimpy. But attention is a zero sum game. If you can choose what to work on, and you choose a project that's not the best one (or at least a good one) for you, then it's getting in the way of another project that is. And at 50 there was some opportunity cost to screwing around.\n\nI started writing essays again, and wrote a bunch of new ones over the next few months. I even wrote a couple that weren't about startups. Then in March 2015 I started working on Lisp again.\n\nThe distinctive thing about Lisp is that its core is a language defined by writing an interpreter in itself. It wasn't originally intended as a programming language in the ordinary sense. It was meant to be a formal model of computation, an alternative to the Turing machine. If you want to write an interpreter for a language in itself, what's the minimum set of predefined operators you need? The Lisp that John McCarthy invented, or more accurately discovered, is an answer to that question. [19]\n\nMcCarthy didn't realize this Lisp could even be used to program computers till his grad student Steve Russell suggested it. Russell translated McCarthy's interpreter into IBM 704 machine language, and from that point Lisp started also to be a programming language in the ordinary sense. But its origins as a model of computation gave it a power and elegance that other languages couldn't match. It was this that attracted me in college, though I didn't understand why at the time.\n\nMcCarthy's 1960 Lisp did nothing more than interpret Lisp expressions. It was missing a lot of things you'd want in a programming language. So these had to be added, and when they were, they weren't defined using McCarthy's original axiomatic approach. That wouldn't have been feasible at the time. McCarthy tested his interpreter by hand-simulating the execution of programs. But it was already getting close to the limit of interpreters you could test that way — indeed, there was a bug in it that McCarthy had overlooked. To test a more complicated interpreter, you'd have had to run it, and computers then weren't powerful enough.\n\nNow they are, though. Now you could continue using McCarthy's axiomatic approach till you'd defined a complete programming language. And as long as every change you made to McCarthy's Lisp was a discoveredness-preserving transformation, you could, in principle, end up with a complete language that had this quality. Harder to do than to talk about, of course, but if it was possible in principle, why not try? So I decided to take a shot at it. It took 4 years, from March 26, 2015 to October 12, 2019. It was fortunate that I had a precisely defined goal, or it would have been hard to keep at it for so long.\n\nI wrote this new Lisp, called Bel, in itself in Arc. That may sound like a contradiction, but it's an indication of the sort of trickery I had to engage in to make this work. By means of an egregious collection of hacks I managed to make something close enough to an interpreter written in itself that could actually run. Not fast, but fast enough to test.\n\nI had to ban myself from writing essays during most of this time, or I'd never have finished. In late 2015 I spent 3 months writing essays, and when I went back to working on Bel I could barely understand the code. Not so much because it was badly written as because the problem is so convoluted. When you're working on an interpreter written in itself, it's hard to keep track of what's happening at what level, and errors can be practically encrypted by the time you get them.\n\nSo I said no more essays till Bel was done. But I told few people about Bel while I was working on it. So for years it must have seemed that I was doing nothing, when in fact I was working harder than I'd ever worked on anything. Occasionally after wrestling for hours with some gruesome bug I'd check Twitter or HN and see someone asking \"Does Paul Graham still code?\"\n\nWorking on Bel was hard but satisfying. I worked on it so intensively that at any given time I had a decent chunk of the code in my head and could write more there. I remember taking the boys to the coast on a sunny day in 2015 and figuring out how to deal with some problem involving continuations while I watched them play in the tide pools. It felt like I was doing life right. I remember that because I was slightly dismayed at how novel it felt. The good news is that I had more moments like this over the next few years.\n\nIn the summer of 2016 we moved to England. We wanted our kids to see what it was like living in another country, and since I was a British citizen by birth, that seemed the obvious choice. We only meant to stay for a year, but we liked it so much that we still live there. So most of Bel was written in England.\n\nIn the fall of 2019, Bel was finally finished. Like McCarthy's original Lisp, it's a spec rather than an implementation, although like McCarthy's Lisp it's a spec expressed as code.\n\nNow that I could write essays again, I wrote a bunch about topics I'd had stacked up. I kept writing essays through 2020, but I also started to think about other things I could work on. How should I choose what to do? Well, how had I chosen what to work on in the past? I wrote an essay for myself to answer that question, and I was surprised how long and messy the answer turned out to be. If this surprised me, who'd lived it, then I thought perhaps it would be interesting to other people, and encouraging to those with similarly messy lives. So I wrote a more detailed version for others to read, and this is the last sentence of it.\n\n\n\n\n\n\n\n\n\nNotes\n\n[1] My experience skipped a step in the evolution of computers: time-sharing machines with interactive OSes. I went straight from batch processing to microcomputers, which made microcomputers seem all the more exciting.\n\n[2] Italian words for abstract concepts can nearly always be predicted from their English cognates (except for occasional traps like polluzione). It's the everyday words that differ. So if you string together a lot of abstract concepts with a few simple verbs, you can make a little Italian go a long way.\n\n[3] I lived at Piazza San Felice 4, so my walk to the Accademia went straight down the spine of old Florence: past the Pitti, across the bridge, past Orsanmichele, between the Duomo and the Baptistery, and then up Via Ricasoli to Piazza San Marco. I saw Florence at street level in every possible condition, from empty dark winter evenings to sweltering summer days when the streets were packed with tourists.\n\n[4] You can of course paint people like still lives if you want to, and they're willing. That sort of portrait is arguably the apex of still life painting, though the long sitting does tend to produce pained expressions in the sitters.\n\n[5] Interleaf was one of many companies that had smart people and built impressive technology, and yet got crushed by Moore's Law. In the 1990s the exponential growth in the power of commodity (i.e. Intel) processors rolled up high-end, special-purpose hardware and software companies like a bulldozer.\n\n[6] The signature style seekers at RISD weren't specifically mercenary. In the art world, money and coolness are tightly coupled. Anything expensive comes to be seen as cool, and anything seen as cool will soon become equally expensive.\n\n[7] Technically the apartment wasn't rent-controlled but rent-stabilized, but this is a refinement only New Yorkers would know or care about. The point is that it was really cheap, less than half market price.\n\n[8] Most software you can launch as soon as it's done. But when the software is an online store builder and you're hosting the stores, if you don't have any users yet, that fact will be painfully obvious. So before we could launch publicly we had to launch privately, in the sense of recruiting an initial set of users and making sure they had decent-looking stores.\n\n[9] We'd had a code editor in Viaweb for users to define their own page styles. They didn't know it, but they were editing Lisp expressions underneath. But this wasn't an app editor, because the code ran when the merchants' sites were generated, not when shoppers visited them.\n\n[10] This was the first instance of what is now a familiar experience, and so was what happened next, when I read the comments and found they were full of angry people. How could I claim that Lisp was better than other languages? Weren't they all Turing complete? People who see the responses to essays I write sometimes tell me how sorry they feel for me, but I'm not exaggerating when I reply that it has always been like this, since the very beginning. It comes with the territory. An essay must tell readers things they don't already know, and some people dislike being told such things.\n\n[11] People put plenty of stuff on the internet in the 90s of course, but putting something online is not the same as publishing it online. Publishing online means you treat the online version as the (or at least a) primary version.\n\n[12] There is a general lesson here that our experience with Y Combinator also teaches: Customs continue to constrain you long after the restrictions that caused them have disappeared. Customary VC practice had once, like the customs about publishing essays, been based on real constraints. Startups had once been much more expensive to start, and proportionally rare. Now they could be cheap and common, but the VCs' customs still reflected the old world, just as customs about writing essays still reflected the constraints of the print era.\n\nWhich in turn implies that people who are independent-minded (i.e. less influenced by custom) will have an advantage in fields affected by rapid change (where customs are more likely to be obsolete).\n\nHere's an interesting point, though: you can't always predict which fields will be affected by rapid change. Obviously software and venture capital will be, but who would have predicted that essay writing would be?\n\n[13] Y Combinator was not the original name. At first we were called Cambridge Seed. But we didn't want a regional name, in case someone copied us in Silicon Valley, so we renamed ourselves after one of the coolest tricks in the lambda calculus, the Y combinator.\n\nI picked orange as our color partly because it's the warmest, and partly because no VC used it. In 2005 all the VCs used staid colors like maroon, navy blue, and forest green, because they were trying to appeal to LPs, not founders. The YC logo itself is an inside joke: the Viaweb logo had been a white V on a red circle, so I made the YC logo a white Y on an orange square.\n\n[14] YC did become a fund for a couple years starting in 2009, because it was getting so big I could no longer afford to fund it personally. But after Heroku got bought we had enough money to go back to being self-funded.\n\n[15] I've never liked the term \"deal flow,\" because it implies that the number of new startups at any given time is fixed. This is not only false, but it's the purpose of YC to falsify it, by causing startups to be founded that would not otherwise have existed.\n\n[16] She reports that they were all different shapes and sizes, because there was a run on air conditioners and she had to get whatever she could, but that they were all heavier than she could carry now.\n\n[17] Another problem with HN was a bizarre edge case that occurs when you both write essays and run a forum. When you run a forum, you're assumed to see if not every conversation, at least every conversation involving you. And when you write essays, people post highly imaginative misinterpretations of them on forums. Individually these two phenomena are tedious but bearable, but the combination is disastrous. You actually have to respond to the misinterpretations, because the assumption that you're present in the conversation means that not responding to any sufficiently upvoted misinterpretation reads as a tacit admission that it's correct. But that in turn encourages more; anyone who wants to pick a fight with you senses that now is their chance.\n\n[18] The worst thing about leaving YC was not working with Jessica anymore. We'd been working on YC almost the whole time we'd known each other, and we'd neither tried nor wanted to separate it from our personal lives, so leaving was like pulling up a deeply rooted tree.\n\n[19] One way to get more precise about the concept of invented vs discovered is to talk about space aliens. Any sufficiently advanced alien civilization would certainly know about the Pythagorean theorem, for example. I believe, though with less certainty, that they would also know about the Lisp in McCarthy's 1960 paper.\n\nBut if so there's no reason to suppose that this is the limit of the language that might be known to them. Presumably aliens need numbers and errors and I/O too. So it seems likely there exists at least one path out of McCarthy's Lisp along which discoveredness is preserved.\n\n\n\nThanks to Trevor Blackwell, John Collison, Patrick Collison, Daniel Gackle, Ralph Hazell, Jessica Livingston, Robert Morris, and Harj Taggar for reading drafts of this.\n"
  },
  {
    "path": "pyopenagi/agents/example/rag_agent/meta_requirements.txt",
    "content": "langchain_core==0.2.1\nllama_index==0.10.39\nllama_index.embeddings.huggingface==0.2.0\nllama-index-vector-stores-chroma==0.1.8\nchromadb==0.5.0\n"
  },
  {
    "path": "pyopenagi/agents/example/rec_agent/agent.py",
    "content": "\nfrom ...react_agent import ReactAgent\n\nclass RecAgent(ReactAgent):\n    def __init__(self,\n                 agent_name,\n                 task_input,\n                 agent_process_factory,\n                 log_mode\n        ):\n        ReactAgent.__init__(self, agent_name, task_input, agent_process_factory, log_mode)\n\n    def automatic_workflow(self):\n        return super().automatic_workflow()\n\n    def manual_workflow(self):\n        workflow = [\n            {\n                \"message\": \"identify the tool that you need to call to obtain information.\",\n                \"tool_use\": [\"google_search\"]\n            },\n            {\n                \"message\": \"based on the information, give recommendations for the user based on the constrains. \",\n                \"tool_use\": []\n            }\n        ]\n        return workflow\n\n    def run(self):\n        return super().run()\n"
  },
  {
    "path": "pyopenagi/agents/example/rec_agent/config.json",
    "content": "{\n    \"name\": \"RecAgent\",\n    \"description\": [\n        \"You are an expert who is good at recommending TV series and movies.\"\n    ],\n    \"tools\": [\"google/google_search\"],\n    \"meta\": {\n\t\t\"author\": \"example\",\n\t\t\"version\": \"0.0.1\",\n\t\t\"license\": \"CC0\"\n\t}\n}\n"
  },
  {
    "path": "pyopenagi/agents/example/rec_agent/meta_requirements.txt",
    "content": ""
  },
  {
    "path": "pyopenagi/agents/example/story_teller/agent.py",
    "content": "from ...react_agent import ReactAgent\n\nimport os\nclass StoryTeller(ReactAgent):\n    def __init__(self,\n                 agent_name,\n                 task_input,\n                 agent_process_factory,\n                 log_mode: str\n        ):\n        ReactAgent.__init__(self, agent_name, task_input, agent_process_factory, log_mode)\n        # self.workflow_mode = \"automatic\"\n        self.workflow_mode = \"manual\"\n\n    def manual_workflow(self):\n        workflow = [\n            {\n                \"message\": \"Determine the story genre and theme based on user input.\",\n                \"tool_use\": []\n            },\n            {\n                \"message\": \"Generate initial story plot and characters.\",\n                \"tool_use\": []\n            },\n            {\n                \"message\": \"Create visual representations for the main character.\",\n                \"tool_use\": [\"text_to_image\"]\n            },\n            {\n                \"message\": \"Write descriptive text for each image and analyze each image\",\n                \"tool_use\": [\"doc_question_answering\"]\n            },\n            {\n                \"message\": \"Incorporate it into the story narrative.\",\n                \"tool_use\": []\n            }\n        ]\n        return workflow\n\n    def check_path(self, tool_calls):\n        script_path = os.path.abspath(__file__)\n        save_dir = os.path.join(os.path.dirname(script_path), \"output\") # modify the customized output path for saving outputs\n        if not os.path.exists(save_dir):\n            os.makedirs(save_dir)\n        for tool_call in tool_calls:\n            try:\n                for k in tool_call[\"parameters\"]:\n                    if \"path\" in k:\n                        path = tool_call[\"parameters\"][k]\n                        if not path.startswith(save_dir):\n                            tool_call[\"parameters\"][k] = os.path.join(save_dir, os.path.basename(path))\n            except Exception:\n                continue\n        return tool_calls\n\n    def run(self):\n        return super().run()\n"
  },
  {
    "path": "pyopenagi/agents/example/story_teller/config.json",
    "content": "{\n    \"name\": \"story_teller\",\n    \"description\": [\n        \"You are a creative storyteller. Given a genre, setting, or character, you can craft engaging narratives. \",\n        \"You can incorporate images to enhance the storytelling experience and even provide audio descriptions of scenes.\"\n    ],\n    \"tools\": [\n        \"stability-ai/text_to_image\",\n        \"impira/doc_question_answering\"\n    ],\n    \"meta\": {\n        \"author\": \"example\",\n        \"version\": \"0.0.1\",\n        \"license\": \"CC0\"\n    }\n}\n"
  },
  {
    "path": "pyopenagi/agents/example/story_teller/meta_requirements.txt",
    "content": ""
  },
  {
    "path": "pyopenagi/agents/example/tech_support_agent/agent.py",
    "content": "from ...react_agent import ReactAgent\n\nclass TechSupportAgent(ReactAgent):\n    def __init__(self,\n                 agent_name,\n                 task_input,\n                 agent_process_factory,\n                 log_mode: str\n        ):\n        ReactAgent.__init__(self, agent_name, task_input, agent_process_factory, log_mode)\n        self.workflow_mode = \"manual\"\n\n    def automatic_workflow(self):\n        return super().automatic_workflow()\n\n    def manual_workflow(self):\n        workflow = [\n            {\n                \"message\": \"identify the user's technical issue or requirement\",\n                \"tool_use\": []\n            },\n            {\n                \"message\": \"search for troubleshooting steps for the identified issue\",\n                \"tool_use\": [\"google_search\"]\n            },\n            {\n                \"message\": \"organize the above information and summarize the solution\",\n                \"tool_use\": []\n            }\n        ]\n        return workflow\n\n    def run(self):\n        return super().run()\n"
  },
  {
    "path": "pyopenagi/agents/example/tech_support_agent/config.json",
    "content": "{\n    \"name\": \"tech_support_agent\",\n    \"description\": [\n        \"You are an expert specialized in providing technical support, \",\n        \"including troubleshooting, software recommendations, and updates.\"\n    ],\n    \"tools\": [\n        \"google/google_search\"\n    ],\n    \"meta\": {\n        \"author\": \"example\",\n        \"version\": \"0.0.1\",\n        \"license\": \"CC0\"\n    }\n}\n"
  },
  {
    "path": "pyopenagi/agents/example/tech_support_agent/meta_requirements.txt",
    "content": "arxiv\nwikipedia\n"
  },
  {
    "path": "pyopenagi/agents/example/transcribe_agent/agent.py",
    "content": "from ...react_agent import ReactAgent\nclass TranscribeAgent(ReactAgent):\n    def __init__(self,\n                 agent_name,\n                 task_input,\n                 agent_process_factory,\n                 log_mode: str\n        ):\n        ReactAgent.__init__(self, agent_name, task_input, agent_process_factory, log_mode)\n        self.workflow_mode = \"manual\"\n    def manual_workflow(self):\n        workflow = [\n                {\n                    \"message\": \"figure out what to do with the audio\",\n                    \"tool_use\": [ \"transcriber/transcriber\"],\n                    },\n                {\n                    \"message\": \"organize the information and respond to the user\",\n                    \"tool_use\": [ ],\n                    },\n                ]\n        return workflow\n\n    def run(self):\n        return super().run()\n"
  },
  {
    "path": "pyopenagi/agents/example/transcribe_agent/config.json",
    "content": "{\n    \"name\": \"transcribe_agent\",\n    \"description\": [\n        \"You are an agent who can transcribe audio from the microphone into text. \"\n    ],\n    \"tools\": [\n        \"transcriber/transcriber\"\n    ],\n    \"meta\": {\n        \"author\": \"Om Raheja\",\n        \"version\": \"0.0.1\",\n        \"license\": \"CC0\"\n    }\n}\n"
  },
  {
    "path": "pyopenagi/agents/example/transcribe_agent/meta_requirements.txt",
    "content": "RealtimeSTT"
  },
  {
    "path": "pyopenagi/agents/example/travel_agent/agent.py",
    "content": "from ...react_agent import ReactAgent\nclass TravelAgent(ReactAgent):\n    def __init__(self,\n                 agent_name,\n                 task_input,\n                 agent_process_factory,\n                 log_mode: str\n        ):\n        ReactAgent.__init__(self, agent_name, task_input, agent_process_factory, log_mode)\n\n    def automatic_workflow(self):\n        return super().automatic_workflow()\n\n    def manual_workflow(self):\n        workflow = [\n            {\n                \"message\": \"identify the destination and search for hotel locations\",\n                \"tool_use\": [\"hotel_location_search\"]\n            },\n            {\n                \"message\": \"based on the hotel locations, find suitable hotels using the hotel_search tool, and select the best one. \",\n                \"tool_use\": None\n            },\n            {\n                \"message\": \"get detailed information about the selected hotel\",\n                \"tool_use\": [\"get_hotel_details\"]\n            },\n            {\n                \"message\": [\"search for the nearest airport to the origin\"],\n                \"tool_use\": [\"airport_search\"]\n            },\n            {\n                \"message\": [\"search for the nearest airport to the destination\"],\n                \"tool_use\": [\"airport_search\"]\n            },\n            {\n                \"message\": [\"find available flights to the destination airport using the correct date\"],\n                \"tool_use\": [\"flight_search\"]\n            },\n            {\n                \"message\": [\"search for restaurant locations near destination\"],\n                \"tool_use\": [\"restaurant_location_search\"]\n            },\n            {\n                \"message\": [\"based on the restaurant locations, find suitable restaurants\"],\n                \"tool_use\": [\"restaurant_search\"]\n            },\n            {\n                \"message\": [\"get detailed information about the selected restaurants\"],\n                \"tool_use\": [\"get_restaurant_details\"]\n            },\n            {\n                \"message\": [\"Gather additional relevant information about the destination the user is visiting\"],\n                \"tool_use\": [\"wikipedia\"]\n            },\n            {\n                \"message\": [\"integrate the information gathered from the previous steps to provide a comprehensive travel plan\"],\n                \"tool_use\": None\n            }\n        ]\n        return workflow\n\n    def run(self):\n        return super().run()\n"
  },
  {
    "path": "pyopenagi/agents/example/travel_agent/config.json",
    "content": "{\n\t\"name\": \"travel_agent\",\n\t\"description\": [\n\t\t\"You are an expert in planning and managing travel itineraries.\"\n\t],\n\t\"tools\": [\n\t\t\"trip_advisor/\"\n\t],\n\t\"meta\": {\n\t\t\"author\": \"example\",\n\t\t\"version\": \"0.0.1\",\n\t\t\"license\": \"CC0\"\n\t}\n}\n"
  },
  {
    "path": "pyopenagi/agents/example/travel_agent/meta_requirements.txt",
    "content": ""
  },
  {
    "path": "pyopenagi/agents/example/travel_planner_agent/README.md",
    "content": "# Travel Planner Agent\n\n## Introduction\n\nThe Travel Planner Agent is replicated from the RecAgent used in the paper \"TravelPlanner: A Benchmark for Real-World Planning with Language Agents\".\n\n## Start\n\nThis agent depends on the [database](https://drive.google.com/file/d/1pF1Sw6pBmq2sFkJvm-LzJOqrmfWoQgxE/view). Please download it and place it in the `pyopenagi/environments/` directory, then rename the 'database' as 'travelPlanner', like `pyopenagi/environments/travelPlanner`.\n\nThen submit an agent like:\n\n```python\nsubmitAgent(\n        agent_name=\"example/travel_planner_agent\",\n        task_input=\"Please plan a trip for me starting from Sarasota to Chicago for 3 days, from March 22nd to March 24th, 2022. The budget for this trip is set at $1,900.\"\n    )\n```\n\nThen run\n```python\npython main.py --llm_name <your llm name>\n```\nsuch as\n```python\npython main.py --llm_name gpt-4o-mini\n```\n\n[Others Guide](https://github.com/agiresearch/AIOS)\n"
  },
  {
    "path": "pyopenagi/agents/example/travel_planner_agent/agent.py",
    "content": "import re\nimport time\nimport os\n\nfrom ...react_agent import ReactAgent\n\nfrom ....utils.chat_template import Query\n\nfrom typing import List, Set\n\nfrom .prompts import ZEROSHOT_REACT_INSTRUCTION, PLANNER_INSTRUCTION\n\nfrom pandas import DataFrame\n\nactionMapping = {\"FlightSearch\": \"flights\",\n                 \"AttractionSearch\": \"attractions\",\n                 \"GoogleDistanceMatrix\": \"google_distance_matrix\",\n                 \"AccommodationSearch\": \"accommodations\",\n                 \"RestaurantSearch\": \"restaurants\",\n                 \"Planner\": \"planner\",\n                 \"NotebookWrite\": \"notebook\",\n                 \"CitySearch\": \"cities\"}\n\nINVALID_ACTION = \"invalidAction\"\n\n\nclass TravelPlannerAgent(ReactAgent):\n    \"\"\"Reproduced the ReActAgent from the paper 👉\n      《TravelPlanner: A Benchmark for Real-World Planning with Language Agents》\n    \"\"\"\n\n    def __init__(self,\n                 agent_name,\n                 task_input,\n                 agent_process_factory,\n                 log_mode: str,\n                 mode: str = 'zero_shot',\n                 max_rounds: int = 30,\n                 max_retries: int = 3,\n                 illegal_early_stop_patience: int = 3,\n                 city_file_path='../../../environments/travelPlanner/background/citySet.txt'\n                 ):\n        ReactAgent.__init__(self, agent_name, task_input, agent_process_factory, log_mode)\n\n        self.answer = ''\n        self.max_rounds = max_rounds\n        self.mode = mode\n        self.finished = False\n\n        self.current_observation = ''\n\n        if self.mode == 'zero_shot':\n            self.agent_prompt = ''\n\n        self.illegal_early_stop_patience = illegal_early_stop_patience\n        self.max_retries = max_retries\n        self.retry_record = {key: 0 for key in self.tool_list.keys()}\n        self.retry_record[\"planner\"] = 0\n        self.retry_record[INVALID_ACTION] = 0\n\n        self.last_actions = []\n\n        self.city_set = self.load_city(city_set_path=city_file_path)\n\n    def automatic_workflow(self):\n        return super().automatic_workflow()\n\n    def manual_workflow(self):\n        return super().manual_workflow()\n\n    def run(self):\n        self.build_system_instruction()\n\n        while not self.is_halted() and not self.is_finished():\n            # request llm for thought\n            self.messages.append({\n                \"role\": \"user\", \"content\": f'Thought {self.rounds + 1}: '\n            })\n            response, start_times, end_times, waiting_times, turnaround_times = self.get_response(\n                query=Query(\n                    messages=self.messages,\n                    tools=None\n                )\n            )\n            self.request_waiting_times.extend(waiting_times)\n            self.request_turnaround_times.extend(turnaround_times)\n            if self.rounds == 0:\n                self.set_start_time(start_times[0])\n\n            thought = response.response_message\n            self.messages[-1]['content'] += thought\n            self.logger.log(f\"Thought {self.rounds + 1}: {thought}\\n\", level=\"info\")\n\n            # request llm for action\n            self.messages.append({\n                \"role\": \"user\", \"content\": f'Action {self.rounds + 1}: '\n            })\n            response, start_times, end_times, waiting_times, turnaround_times = self.get_response(\n                query=Query(\n                    messages=self.messages,\n                    tools=None\n                )\n            )\n            self.request_waiting_times.extend(waiting_times)\n            self.request_turnaround_times.extend(turnaround_times)\n\n            action = response.response_message\n            if action is None or action == '' or action == '\\n':\n                self.messages[-1]['content'] += \"\"\" Your action is filtered due to content.\n                  Please make sure your action does not start with ['\\\\n', 'Thought', 'Action', 'Observation']\n                  and assume all the actions are permitted in this environment and take the action again.\"\"\"\n            else:\n                self.messages[-1]['content'] += ' ' + action\n\n            self.logger.log(f\"Action {self.rounds + 1}: {action}\\n\", level=\"info\")\n\n            if len(self.last_actions) > 0 and self.last_actions[-1] != action:\n                self.last_actions.clear()\n            else:\n                self.last_actions.append(action)\n\n            # examine if the same action has been repeated 3 times consecutively\n            if len(self.last_actions) == 3:\n                self.logger.log(\"The same action has been repeated 3 times consecutively. So we stop here.\\n\",\n                                level=\"info\")\n                self.finished = True\n                return {\n                    \"agent_name\": self.agent_name,\n                    \"result\": \"Failed to generate a valid plan because a deadlock.\",\n                    \"rounds\": self.rounds,\n                    \"agent_waiting_time\": None,\n                    \"agent_turnaround_time\": None,\n                    \"request_waiting_times\": self.request_waiting_times,\n                    \"request_turnaround_times\": self.request_turnaround_times,\n                }\n\n            # request tools for observation\n            self.messages.append({\n                \"role\": \"user\", \"content\": f'Observation {self.rounds + 1}: '\n            })\n\n            none_action = (action is None or action == '' or action == '\\n')\n            if none_action:\n                self.messages[-1]['content'] += \"\"\"No feedback from the environment due to the null action.\n                  Please make sure your action does not start with [Thought, Action, Observation].\"\"\"\n            else:\n                action_type, action_arg = parse_action(action)\n\n                if action_type != \"Planner\":\n                    if action_type in actionMapping:\n                        pending_action = actionMapping[action_type]\n                    else:\n                        pending_action = INVALID_ACTION\n\n                    if self.retry_record[pending_action] + 1 > self.max_retries:\n                        action_type = \"Planner\"\n                        self.logger.log(f\"{pending_action} early stop due to {self.max_retries} max retries.\\n\", \"info\")\n                        self.finished = True\n                        continue\n\n                self.action_dispatch(action_type, action_arg)\n\n                self.messages[-1]['content'] += self.current_observation\n\n            if none_action:\n                self.logger.log(\n                    f\"Observation {self.rounds + 1}: No feedback from the environment due to the null action.\\n\")\n            else:\n                self.logger.log(f\"Observation {self.rounds + 1}: {self.current_observation}\\n\", \"info\")\n\n            if action_type and action_type == 'Planner' and self.retry_record['planner'] == 0:\n                self.finished = True\n                self.answer = self.current_observation\n                continue\n\n            self.rounds += 1\n\n        self.set_status(\"done\")\n        self.set_end_time(time=time.time())\n\n        return {\n            \"agent_name\": self.agent_name,\n            \"result\": self.answer,\n            \"rounds\": self.rounds,\n            \"agent_waiting_time\": self.start_time - self.created_time,\n            \"agent_turnaround_time\": self.end_time - self.created_time,\n            \"request_waiting_times\": self.request_waiting_times,\n            \"request_turnaround_times\": self.request_turnaround_times,\n        }\n\n    def build_system_instruction(self):\n        self.messages.append({\n            \"role\": \"user\", \"content\": ZEROSHOT_REACT_INSTRUCTION\n        })\n        self.messages.append({\n            \"role\": \"user\", \"content\": \"Query: \" + self.task_input\n        })\n\n    def build_planner_instruction(self, query: str, text: str) -> None:\n        self.messages.clear()\n        # simply request once\n        self.messages.append({\n            \"role\": \"user\", \"content\": PLANNER_INSTRUCTION.format(text=text, query=query)\n        })\n\n    def is_halted(self) -> bool:\n        return self.rounds > self.max_rounds\n\n    def is_finished(self) -> bool:\n        return self.finished\n\n    def action_dispatch(self, action_type: str, action_arg: str) -> None:\n        \"\"\"call coresponding tools by action_type\n\n        Args:\n            action_type (str): type\n            action_arg (str): args\n        \"\"\"\n\n        if action_type == 'Planner':\n            query = action_arg\n            text = self.tool_list[actionMapping[\"NotebookWrite\"]].list_all()\n\n            # reset the context and build planner agent context\n            self.build_planner_instruction(text, query)\n\n            response, start_times, end_times, waiting_times, turnaround_times = self.get_response(\n                query=Query(\n                    messages=self.messages,\n                    tools=None\n                )\n            )\n            self.request_waiting_times.extend(waiting_times)\n            self.request_turnaround_times.extend(turnaround_times)\n\n            self.current_observation = to_string(response.response_message)\n            self.answer = self.current_observation\n            self.current_observation = \"\\n\" + self.current_observation  # align output\n            self.__reset_record()\n\n        elif action_type == 'NotebookWrite':\n            try:\n                action_name = actionMapping[action_type]\n                self.current_observation = to_string(self.tool_list[action_name].run(self.current_data, action_arg))\n                self.__reset_record()\n\n            except Exception as e:\n                self.retry_record[action_name] += 1\n                self.current_observation = to_string(e)\n\n        elif action_type in actionMapping.keys():\n            try:\n                action_name = actionMapping[action_type]\n                args = action_arg.split(', ')\n                self.current_data = self.tool_list[action_name].run(*args)\n                self.current_observation = to_string(self.current_data)\n                self.__reset_record()\n\n            except Exception as e:\n                self.retry_record[action_name] += 1\n                self.current_observation = to_string(e)\n\n        else:\n            self.retry_record[INVALID_ACTION] += 1\n            self.current_observation = f'''{action_type} is Invalid Action. Valid Actions are\n              FlightSearch[Departure City, Destination City, Date] /\n              AccommodationSearch[City] /\n              RestaurantSearch[City] /\n              NotebookWrite[Short Description] /\n              AttractionSearch[City] /\n              CitySearch[State] /\n              GoogleDistanceMatrix[Origin, Destination, Mode] /\n              Planner[Query].'''\n\n    def load_city(self, city_set_path: str) -> Set[str]:\n        city_set = []\n        current_dir = os.path.dirname(os.path.abspath(__file__))\n        city_set_path = os.path.join(current_dir, city_set_path)\n        lines = open(city_set_path, 'r').read().strip().split('\\n')\n        for unit in lines:\n            city_set.append(unit)\n        return set(city_set)\n\n    def __reset_record(self) -> None:\n        self.retry_record = {key: 0 for key in self.retry_record}\n        self.retry_record[INVALID_ACTION] = 0\n\n\ndef parse_action(string: str):\n    \"\"\"match action type and action arg\n\n    Args:\n        string (str): string will be matched\n\n    Returns:\n        tuple[str, str]: action type and action arg\n    \"\"\"\n    pattern = r'^(\\w+)\\[(.+)\\]$'\n    match = re.match(pattern, string)\n\n    try:\n        if match:\n            action_type = match.group(1)\n            action_arg = match.group(2)\n            return action_type, action_arg\n        else:\n            return None, None\n\n    except Exception:\n        return None, None\n\n\ndef validate_date_format(date_list: List[str]) -> bool:\n    for date in date_list:\n        pattern = r'^\\d{4}-\\d{2}-\\d{2}$'\n        if not re.match(pattern, date):\n            return False\n    return True\n\n\ndef valid_city_format(city_list: List[str], city_set: Set[str]) -> bool:\n    return set(city_list).issubset(city_set)\n\n\ndef to_string(data) -> str:\n    if data is not None:\n        if type(data) is DataFrame:\n            return data.to_string(index=False)\n        else:\n            return str(data)\n    else:\n        return str(None)\n"
  },
  {
    "path": "pyopenagi/agents/example/travel_planner_agent/config.json",
    "content": "{\n\t\"name\": \"travel_planner_agent\",\n\t\"description\": [\n\t\t\"TravelPlanner: A Benchmark for Real-World Planning with Language Agents\"\n\t],\n\t\"tools\": [\n\t\t\"travel_planner/accommodations\",\n        \"travel_planner/attractions\",\n        \"travel_planner/cities\",\n        \"travel_planner/flights\",\n        \"travel_planner/google_distance_matrix\",\n        \"travel_planner/notebook\",\n        \"travel_planner/restaurants\"\n\t],\n\t\"meta\": {\n\t\t\"author\": \"example\",\n\t\t\"version\": \"0.0.1\",\n\t\t\"license\": \"CC0\"\n\t}\n}\n"
  },
  {
    "path": "pyopenagi/agents/example/travel_planner_agent/meta_requirements.txt",
    "content": ""
  },
  {
    "path": "pyopenagi/agents/example/travel_planner_agent/prompts.py",
    "content": "ZEROSHOT_REACT_INSTRUCTION = \"\"\"Collect information for a query plan using interleaving 'Thought', 'Action', and 'Observation' steps. Ensure you gather valid information related to transportation, dining, attractions, and accommodation. All information should be written in Notebook, which will then be input into the Planner tool. Note that the nested use of tools is prohibited. 'Thought' can reason about the current situation, and 'Action' can have 8 different types:\n(1) FlightSearch[Departure City, Destination City, Date]:\nDescription: A flight information retrieval tool.\nParameters:\nDeparture City: The city you'll be flying out from.\nDestination City: The city you aim to reach.\nDate: The date of your travel in YYYY-MM-DD format.\nExample: FlightSearch[New York, London, 2022-10-01] would fetch flights from New York to London on October 1, 2022.\n\n(2) GoogleDistanceMatrix[Origin, Destination, Mode]:\nDescription: Estimate the distance, time and cost between two cities.\nParameters:\nOrigin: The departure city of your journey.\nDestination: The destination city of your journey.\nMode: The method of transportation. Choices include 'self-driving' and 'taxi'.\nExample: GoogleDistanceMatrix[Paris, Lyon, self-driving] would provide driving distance, time and cost between Paris and Lyon.\n\n(3) AccommodationSearch[City]:\nDescription: Discover accommodations in your desired city.\nParameter: City - The name of the city where you're seeking accommodation.\nExample: AccommodationSearch[Rome] would present a list of hotel rooms in Rome.\n\n(4) RestaurantSearch[City]:\nDescription: Explore dining options in a city of your choice.\nParameter: City – The name of the city where you're seeking restaurants.\nExample: RestaurantSearch[Tokyo] would show a curated list of restaurants in Tokyo.\n\n(5) AttractionSearch[City]:\nDescription: Find attractions in a city of your choice.\nParameter: City – The name of the city where you're seeking attractions.\nExample: AttractionSearch[London] would return attractions in London.\n\n(6) CitySearch[State]\nDescription: Find cities in a state of your choice.\nParameter: State – The name of the state where you're seeking cities.\nExample: CitySearch[California] would return cities in California.\n\n(7) NotebookWrite[Short Description]\nDescription: Writes a new data entry into the Notebook tool with a short description. This tool should be used immediately after FlightSearch, AccommodationSearch, AttractionSearch, RestaurantSearch or GoogleDistanceMatrix. Only the data stored in Notebook can be seen by Planner. So you should write all the information you need into Notebook.\nParameters: Short Description - A brief description or label for the stored data. You don't need to write all the information in the description. The data you've searched for will be automatically stored in the Notebook.\nExample: NotebookWrite[Flights from Rome to Paris in 2022-02-01] would store the informatrion of flights from Rome to Paris in 2022-02-01 in the Notebook.\n\n(8) Planner[Query]\nDescription: A smart planning tool that crafts detailed plans based on user input and the information stroed in Notebook.\nParameters:\nQuery: The query from user.\nExample: Planner[Give me a 3-day trip plan from Seattle to New York] would return a detailed 3-day trip plan.\nYou should use as many as possible steps to collect engough information to input to the Planner tool.\n\nEach action only calls one function once. Do not add any description in the action.\n\nEach reponse only execute one step of 'Thought', 'Action', 'Observation'. If you have a step 'Thought', don't generate 'Action'.\n\"\"\"\n\nPLANNER_INSTRUCTION = \"\"\"You are a proficient planner. Based on the provided information and query, please give me a detailed plan, including specifics such as flight numbers (e.g., F0123456), restaurant names, and accommodation names. Note that all the information in your plan should be derived from the provided data. You must adhere to the format given in the example. Additionally, all details should align with commonsense. The symbol '-' indicates that information is unnecessary. For example, in the provided sample, you do not need to plan after returning to the departure city. When you travel to two cities in one day, you should note it in the 'Current City' section as in the example (i.e., from A to B).\n\n***** Example *****\nQuery: Could you create a travel plan for 7 people from Ithaca to Charlotte spanning 3 days, from March 8th to March 14th, 2022, with a budget of $30,200?\nTravel Plan:\nDay 1:\nCurrent City: from Ithaca to Charlotte\nTransportation: Flight Number: F3633413, from Ithaca to Charlotte, Departure Time: 05:38, Arrival Time: 07:46\nBreakfast: Nagaland's Kitchen, Charlotte\nAttraction: The Charlotte Museum of History, Charlotte\nLunch: Cafe Maple Street, Charlotte\nDinner: Bombay Vada Pav, Charlotte\nAccommodation: Affordable Spacious Refurbished Room in Bushwick!, Charlotte\n\nDay 2:\nCurrent City: Charlotte\nTransportation: -\nBreakfast: Olive Tree Cafe, Charlotte\nAttraction: The Mint Museum, Charlotte;Romare Bearden Park, Charlotte.\nLunch: Birbal Ji Dhaba, Charlotte\nDinner: Pind Balluchi, Charlotte\nAccommodation: Affordable Spacious Refurbished Room in Bushwick!, Charlotte\n\nDay 3:\nCurrent City: from Charlotte to Ithaca\nTransportation: Flight Number: F3786167, from Charlotte to Ithaca, Departure Time: 21:42, Arrival Time: 23:26\nBreakfast: Subway, Charlotte\nAttraction: Books Monument, Charlotte.\nLunch: Olive Tree Cafe, Charlotte\nDinner: Kylin Skybar, Charlotte\nAccommodation: -\n\n***** Example Ends *****\n\nGiven information: {text}\nQuery: {query}\nTravel Plan:\"\"\"\n"
  },
  {
    "path": "pyopenagi/agents/interact.py",
    "content": "# executable that you can use to upload to the agent hub and download from it\n# we also use this to check dependencies to run agents\n\nimport argparse\nimport json\nimport subprocess\nimport requests\nimport gzip\nimport base64\nimport sys\nimport os\n\n\nclass Interactor:\n    def __init__(self):\n        script_path = os.path.abspath(__file__)\n        script_dir = os.path.dirname(script_path)\n        self.base_folder = script_dir\n\n    def list_available_agents(self) -> list[dict]:\n        \"\"\"List available agents in the database\"\"\"\n        url = \"https://openagi-beta.vercel.app/api/get_all_agents\"\n        response = requests.get(url)\n        response: dict = response.json()\n        agent_list = []\n        for v in list(response.values())[:-1]:\n            agent_list.append({\n                \"agent\": \"/\".join([v[\"author\"], v[\"name\"]])\n            })\n        return agent_list\n\n    def download_agent(self, agent: str) -> None:\n        \"\"\"Download an agent from the database\n\n        Args:\n            agent (str): in the format of \"author/agent_name\"\n        \"\"\"\n        assert \"/\" in agent, 'agent_name should in the format of \"author/agent_name\"'\n        author, name = agent.split(\"/\")\n        # print(author, name)\n        query = f'https://openagi-beta.vercel.app/api/download?author={author}&name={name}'\n        response = requests.get(query)\n        response: dict = response.json()\n\n        agent_folder = os.path.join(self.base_folder, agent)\n\n        if not os.path.exists(agent_folder):\n            os.makedirs(agent_folder)\n\n        encoded_config = response.get('config')\n        encoded_code = response.get(\"code\")\n        encoded_reqs = response.get('dependencies')\n        \n        if (encoded_config is None) or (encoded_code is None) or (encoded_reqs is None):\n            print(\"Agent not found. Try uploading it first?\")\n            return\n\n        self.download_config(\n            self.decompress(encoded_config),\n            agent\n        )\n        self.download_code(\n            self.decompress(encoded_code),\n            agent\n        )\n        self.download_reqs(\n            self.decompress(encoded_reqs),\n            agent\n        )\n\n    def upload_agent(self, agent) -> None:\n        \"\"\"Upload an agent to the database\n\n        Args:\n            agent (str): in the format of \"author/agent_name\"\n        \"\"\"\n        agent_dir = os.path.join(self.base_folder, agent)\n\n        author, name = agent.split(\"/\")\n\n        config_file = os.path.join(agent_dir, \"config.json\")\n        with open(config_file, 'r') as f:\n            config_data: dict[str, dict] = json.load(f)\n\n        meta_data = config_data.get('meta')\n\n        headers = { \"Content-Type\": \"application/json\" }\n\n        # compress python code\n        encoded_code = self.compress(\n            self.minify_python_code(agent_dir)\n        )\n\n        # compress meta_requirements.txt\n        encoded_reqs =  self.compress(\n            self.minify_reqs(agent_dir)\n        )\n\n        # compress config.json\n        config_str = json.dumps(config_data)\n        encoded_config = self.compress(config_str)\n\n        upload_content = {\n            'author': author,\n            'name': name,\n            'version': meta_data.get('version'),\n            'license': meta_data.get('license'),\n            'config': encoded_config,\n            'code': encoded_code,\n            'dependencies': encoded_reqs\n        }\n\n        url = 'https://openagi-beta.vercel.app/api/upload'\n\n        response = requests.post(\n            url,\n            data=json.dumps(upload_content),\n            headers=headers\n        )\n        if response.content:\n            print(\"Uploaded successfully.\")\n\n    def minify_python_code(self, agent_dir):\n        code_path = os.path.join(agent_dir, \"agent.py\")\n        with open(code_path, 'r') as file:\n            lines: list[str] = file.readlines()\n        minified_lines = []\n        for line in lines:\n            stripped_line = line.rstrip()\n            if stripped_line and not stripped_line.lstrip().startswith(\"#\"):\n                minified_lines.append(stripped_line)\n        minified_code = \"\\n\".join(minified_lines)\n        return minified_code\n\n    def minify_reqs(self, agent_dir):\n        req_path = os.path.join(agent_dir, \"meta_requirements.txt\")\n        with open(req_path, 'r') as file:\n            self.reqs: str = file.read()\n        cleaned = [line.strip() for line in self.reqs.split(\n            '\\n') if line.strip() and not line.startswith('#')]\n        minified_reqs = ';'.join(cleaned)\n        return minified_reqs\n\n    def minify_config(self, config_data):\n        minified_config = self.compress(config_data)\n        return minified_config\n\n    def compress(self, minified_data):\n        compressed_data = gzip.compress(minified_data.encode('utf-8'))\n        encoded_data = base64.b64encode(compressed_data)\n        encoded_data = encoded_data.decode('utf-8')\n        return encoded_data\n\n\n    def decompress(self, encoded_data):\n        compressed_data = base64.b64decode(encoded_data)\n        decompressed_data = gzip.decompress(compressed_data)\n        decompressed_data = decompressed_data.decode(\"utf-8\")\n        decompressed_data.replace(\";\", \"\\n\")\n        return decompressed_data\n\n    def download_config(self, config_data, agent) :\n        config_path = os.path.join(self.base_folder, agent, \"config.json\")\n        config_data = json.loads(config_data)\n        with open(config_path, \"w\") as w:\n            json.dump(config_data, w, indent=4)\n\n    def download_reqs(self, reqs_data, agent):\n        reqs_path = os.path.join(self.base_folder, agent, \"meta_requirements.txt\")\n\n        reqs_data = reqs_data.replace(\";\", \"\\n\")\n\n        with open(reqs_path, 'w') as file:\n            file.write(reqs_data)\n\n    def download_code(self, code_data, agent):\n        code_path = os.path.join(self.base_folder, agent, \"agent.py\")\n\n        with open(code_path, 'w', newline='') as file:\n            file.write(code_data)\n\n    def check_reqs_installed(self, agent):\n        # Run the `conda list` command and capture the output\n        reqs_path = os.path.join(self.base_folder, agent, \"meta_requirements.txt\")\n\n        try:\n            result = subprocess.run(['conda', 'list'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n        except Exception:\n            result = subprocess.run(['pip', 'list', '--format=freeze'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n\n        # Decode the output from bytes to string\n        with open(reqs_path, \"r\") as f:\n            reqs = []\n            lines = f.readlines()\n            for line in lines:\n                line = line.replace(\"\\n\", \"\")\n                if \"==\" in line:\n                    reqs.append(line.split(\"==\")[0])\n                else:\n                    reqs.append(line)\n\n        output = result.stdout.decode('utf-8')\n\n        # Extract the list of installed packages\n        installed_packages = [line.split()[0] for line in output.splitlines() if line]\n\n        # Check for each package if it is installed\n        for req in reqs:\n            if req not in installed_packages:\n                return False\n\n        return True\n\n    def install_agent_reqs(self, agent):\n        reqs_path = os.path.join(self.base_folder, agent, \"meta_requirements.txt\")\n        with open (\"deplogs.txt\", \"a\") as f:\n            subprocess.check_call([\n                sys.executable,\n                \"-m\",\n                \"pip\",\n                \"install\",\n                \"-r\",\n                reqs_path],\n                stdout=f,\n                stderr=f\n            )\n        print(\"Installing dependencies for agent: \" + agent + \". Writing to deplogs.txt\")\n\ndef parse_args():\n    parser = argparse.ArgumentParser()\n    parser.add_argument(\"--mode\", choices=[\"download\", \"upload\"])\n    parser.add_argument(\"--agent\", required=True)\n    args = parser.parse_args()\n    return args\n\nif __name__ == '__main__':\n    pass\n    # list_available_agents() # list agents that can be used from db\n\n    args = parse_args()\n    mode = args.mode\n    agent = args.agent\n\n    client = Interactor()\n    # client.check_reqs_installed(agent)\n    # client = Interactor()\n    if mode == \"download\":\n        client.download_agent(agent) # download agents\n\n    else:\n        assert mode == \"upload\"\n        client.upload_agent(agent) # upload agents\n"
  },
  {
    "path": "pyopenagi/agents/om-raheja/transcribe_agent/agent.py",
    "content": "from ...react_agent import ReactAgent\nclass TranscribeAgent(ReactAgent):\n    def __init__(self,\n                 agent_name,\n                 task_input,\n                 agent_process_factory,\n                 log_mode: str\n        ):\n        ReactAgent.__init__(self, agent_name, task_input, agent_process_factory, log_mode)\n        self.workflow_mode = \"automatic\"\n    def manual_workflow(self):\n        pass\n    def run(self):\n        return super().run()"
  },
  {
    "path": "pyopenagi/agents/om-raheja/transcribe_agent/config.json",
    "content": "{\n    \"name\": \"transcribe_agent\",\n    \"description\": [\n        \"You are an agent who can transcribe audio from the microphone into text. \"\n    ],\n    \"tools\": [\n        \"transcriber/transcriber\"\n    ],\n    \"meta\": {\n        \"author\": \"Om Raheja\",\n        \"version\": \"0.0.1\",\n        \"license\": \"CC0\"\n    }\n}"
  },
  {
    "path": "pyopenagi/agents/om-raheja/transcribe_agent/meta_requirements.txt",
    "content": "RealtimeSTT"
  },
  {
    "path": "pyopenagi/agents/react_agent.py",
    "content": "\nfrom .base_agent import BaseAgent\n\nimport time\n\nfrom ..utils.chat_template import Query\n\nimport json\n\nclass ReactAgent(BaseAgent):\n    def __init__(self,\n                 agent_name,\n                 task_input,\n                 agent_process_factory,\n                 log_mode: str\n        ):\n        BaseAgent.__init__(\n            self,\n            agent_name,\n            task_input,\n            agent_process_factory,\n            log_mode\n        )\n\n        self.plan_max_fail_times = 3\n        self.tool_call_max_fail_times = 3\n\n    def build_system_instruction(self):\n        prefix = \"\".join(\n            [\n                \"\".join(self.config[\"description\"])\n            ]\n        )\n\n        plan_instruction = \"\".join(\n            [\n                f'You are given the available tools from the tool list: {json.dumps(self.tool_info)} to help you solve problems. ',\n                'Generate a plan of steps you need to take. ',\n                'The plan must follow the json format as: ',\n                '[',\n                '{\"message\": \"message_value1\",\"tool_use\": [tool_name1, tool_name2,...]}',\n                '{\"message\": \"message_value2\", \"tool_use\": [tool_name1, tool_name2,...]}',\n                '...',\n                ']',\n                'In each step of the planned workflow, you must select the most related tool to use',\n                'Followings are some plan examples:',\n                '[',\n                '{\"message\": \"gather information from arxiv. \", \"tool_use\": [\"arxiv\"]},',\n                '{\"message\", \"write a summarization based on the gathered information. \", \"tool_use\": []}',\n                '];',\n                '[',\n                '{\"message\": \"identify the tool that you need to call to obtain information. \", \"tool_use\": [\"imdb_top_movies\", \"imdb_top_series\"]},',\n                '{\"message\", \"give recommendations for the user based on the information. \", \"tool_use\": []}',\n                '];',\n            ]\n        )\n\n        if self.workflow_mode == \"manual\":\n            self.messages.append(\n                {\"role\": \"system\", \"content\": prefix}\n            )\n\n        else:\n            assert self.workflow_mode == \"automatic\"\n            self.messages.append(\n                {\"role\": \"system\", \"content\": prefix + plan_instruction}\n            )\n\n\n    def automatic_workflow(self):\n        return super().automatic_workflow()\n\n    def manual_workflow(self):\n        pass\n\n    def call_tools(self, tool_calls):\n        # self.logger.log(f\"***** It starts to call external tools *****\\n\", level=\"info\")\n        success = True\n        actions = []\n        observations = []\n\n        # print(tool_calls)\n        for tool_call in tool_calls:\n            # print(tool_call)\n            function_name = tool_call[\"name\"]\n            function_to_call = self.tool_list[function_name]\n            function_params = tool_call[\"parameters\"]\n\n            try:\n                function_response = function_to_call.run(function_params)\n                actions.append(f\"I will call the {function_name} with the params as {function_params}\")\n                observations.append(f\"The output of calling the {function_name} tool is: {function_response}\")\n\n            except Exception:\n                actions.append(\"I fail to call any tools.\")\n                observations.append(f\"The tool parameter {function_params} is invalid.\")\n                success = False\n\n        return actions, observations, success\n\n    def run(self):\n        self.build_system_instruction()\n\n        task_input = self.task_input\n\n        self.messages.append(\n            {\"role\": \"user\", \"content\": task_input}\n        )\n        self.logger.log(f\"{task_input}\\n\", level=\"info\")\n\n        workflow = None\n\n        if self.workflow_mode == \"automatic\":\n            workflow = self.automatic_workflow()\n        else:\n            assert self.workflow_mode == \"manual\"\n            workflow = self.manual_workflow()\n\n        self.messages.append(\n            {\"role\": \"assistant\", \"content\": f\"[Thinking]: The workflow generated for the problem is {json.dumps(workflow)}\"}\n        )\n\n        self.messages.append(\n            {\"role\": \"user\", \"content\": \"[Thinking]: Follow the workflow to solve the problem step by step. \"}\n        )\n\n        if workflow:\n            self.logger.log(f\"Generated workflow is: {workflow}\\n\", level=\"info\")\n        else:\n            self.logger.log(f\"Fail to generate a valid workflow. Invalid JSON?\\n\", level=\"info\")\n\n        try:\n            if workflow:\n                final_result = \"\"\n\n                for i, step in enumerate(workflow):\n                    message = step[\"message\"]\n                    tool_use = step[\"tool_use\"]\n\n                    prompt = f\"At step {i + 1}, you need to: {message}. \"\n                    self.messages.append({\n                        \"role\": \"user\",\n                        \"content\": prompt\n                    })\n                    if tool_use:\n                        selected_tools = self.pre_select_tools(tool_use)\n\n                    else:\n                        selected_tools = None\n\n                    response, start_times, end_times, waiting_times, turnaround_times = self.get_response(\n                        query = Query(\n                            messages = self.messages,\n                            tools = selected_tools\n                        )\n                    )\n\n                    if self.rounds == 0:\n                        self.set_start_time(start_times[0])\n\n                    # execute action\n                    response_message = response.response_message\n\n                    tool_calls = response.tool_calls\n\n                    self.request_waiting_times.extend(waiting_times)\n                    self.request_turnaround_times.extend(turnaround_times)\n\n                    if tool_calls:\n                        for _ in range(self.plan_max_fail_times):\n                            tool_calls = self.check_path(tool_calls)\n                            actions, observations, success = self.call_tools(tool_calls=tool_calls)\n\n                            action_messages = \"[Action]: \" + \";\".join(actions)\n                            observation_messages = \"[Observation]: \" + \";\".join(observations)\n\n                            self.messages.append(\n                                {\n                                    \"role\": \"assistant\",\n                                    \"content\": action_messages + \". \" + observation_messages\n                                }\n                            )\n                            if success:\n                                break\n                    else:\n                        thinkings = response_message\n                        self.messages.append({\n                            \"role\": \"assistant\",\n                            \"content\": thinkings\n                        })\n\n                    if i == len(workflow) - 1:\n                        final_result = self.messages[-1]\n\n                    step_result = self.messages[-1][\"content\"]\n                    self.logger.log(f\"At step {i + 1}, {step_result}\\n\", level=\"info\")\n\n                    self.rounds += 1\n\n                self.set_status(\"done\")\n                self.set_end_time(time=time.time())\n\n                return {\n                    \"agent_name\": self.agent_name,\n                    \"result\": final_result,\n                    \"rounds\": self.rounds,\n                    \"agent_waiting_time\": self.start_time - self.created_time,\n                    \"agent_turnaround_time\": self.end_time - self.created_time,\n                    \"request_waiting_times\": self.request_waiting_times,\n                    \"request_turnaround_times\": self.request_turnaround_times,\n                }\n\n            else:\n                return {\n                    \"agent_name\": self.agent_name,\n                    \"result\": \"Failed to generate a valid workflow in the given times.\",\n                    \"rounds\": self.rounds,\n                    \"agent_waiting_time\": None,\n                    \"agent_turnaround_time\": None,\n                    \"request_waiting_times\": self.request_waiting_times,\n                    \"request_turnaround_times\": self.request_turnaround_times,\n                }\n        except Exception as e:\n            print(e)\n            return {}\n"
  },
  {
    "path": "pyopenagi/data/agent_tasks/README.md",
    "content": "# Agent Tasks\nThis directory test tasks for each agent, containing examples of prompts that could be given to that agent. This is used by `eval.py` when running tests.\n"
  },
  {
    "path": "pyopenagi/data/agent_tasks/example/academic_agent_task.txt",
    "content": "Find recent papers on the impact of social media on mental health in adolescents.\nExplore the potential of AI in early disease detection.\nSummarize key findings from studies on climate change mitigation strategies.\nIdentify research gaps in the field of renewable energy.\nFind papers on the effectiveness of online education compared to traditional classrooms.\nSummarize key findings from studies on the impact of sleep deprivation on cognitive function.\nIdentify research gaps in the field of human-computer interaction.\nFind papers on the relationship between diet and chronic diseases.\nSummarize key findings from studies on the effectiveness of different cancer treatments.\nIdentify research gaps in the field of autonomous vehicles.\nFind papers on the impact of globalization on economic inequality.\nSummarize key findings from studies on the effectiveness of different teaching methods.\nIdentify research gaps in the field of artificial intelligence ethics.\nFind papers on the relationship between physical activity and mental health.\nSummarize key findings from studies on the effectiveness of different drug delivery systems.\nIdentify research gaps in the field of sustainable agriculture.\nFind papers on the impact of technology on human relationships.\nSummarize key findings from studies on the effectiveness of different psychotherapy techniques.\nIdentify research gaps in the field of space exploration.\nFind papers on the relationship between income inequality and social unrest.\nFind recent papers on the use of machine learning for predicting stock market trends.\nExplore the potential of nanotechnology in drug delivery.\nSummarize key findings from studies on the impact of climate change on biodiversity.\nIdentify research gaps in the field of quantum computing.\nFind papers on the effectiveness of online learning platforms for language acquisition.\nSummarize key findings from studies on the relationship between gut microbiota and mental health.\nIdentify research gaps in the field of human-robot interaction.\nFind papers on the impact of air pollution on respiratory health.\nSummarize key findings from studies on the effectiveness of different diabetes management strategies.\nIdentify research gaps in the field of renewable energy storage.\nFind papers on the relationship between social media use and political polarization.\nSummarize key findings from studies on the effectiveness of different educational interventions for children with autism.\nIdentify research gaps in the field of cybersecurity.\nFind papers on the relationship between physical activity and cardiovascular health.\nSummarize key findings from studies on the effectiveness of different pain management techniques.\nIdentify research gaps in the field of precision medicine.\nFind papers on the impact of social media on body image.\nSummarize key findings from studies on the effectiveness of different cognitive behavioral therapy techniques.\nIdentify research gaps in the field of climate change adaptation.\nFind papers on the relationship between income inequality and health outcomes.\nCan AI be used to develop personalized treatment plans for cancer patients?\nWhat is the impact of climate change on agricultural yields in sub-Saharan Africa?\nHow effective are virtual reality-based therapies for treating phobias?\nWhat are the ethical implications of using CRISPR gene editing technology?\nCan wearable devices be used to monitor and prevent chronic diseases?\nHow does social media influence the spread of misinformation?\nWhat is the role of gut microbiota in the development of autoimmune diseases?\nCan machine learning be used to predict natural disasters?\nHow can we improve the accessibility of mental health services for underserved populations?\nWhat are the long-term effects of screen time on children's cognitive development?\nCan artificial intelligence be used to develop new materials with desired properties?\nHow can we reduce food waste and improve food security globally?\nWhat is the impact of sleep deprivation on the immune system?\nHow can we promote sustainable consumption and production patterns?\nWhat are the challenges and opportunities of using blockchain technology in healthcare?\nCan virtual reality be used to improve the rehabilitation process for stroke patients?\nHow can we address the digital divide and ensure equitable access to technology?\nWhat is the role of epigenetics in the development of complex diseases?\nHow can we promote mental health and well-being in the workplace?\nWhat are the potential benefits and risks of using geoengineering to combat climate change?\nSummarize the key findings of the paper \"Attention Is All You Need\" by Vaswani et al.\nFind recent papers on the use of deep learning for image segmentation.\nSummarize the key findings of the paper \"A Large Language Model for Code Generation\" by OpenAI.\nFind recent papers on the impact of artificial intelligence on the job market.\nFind recent papers on the impact of climate change on global health.\nExplore the potential of AI in education.\nSummarize key findings from studies on the effectiveness of different dietary patterns.\nIdentify research gaps in the field of sustainable energy.\nFind papers on the relationship between socioeconomic status and mental health.\nSummarize key findings from studies on the impact of screen time on children's development.\nIdentify research gaps in the field of human-animal interaction.\nFind papers on the effectiveness of different treatments for chronic pain.\nSummarize key findings from studies on the impact of urbanization on biodiversity.\nIdentify research gaps in the field of space colonization.\nFind recent papers on the use of machine learning for natural language processing.\nExplore the potential of nanotechnology in environmental remediation.\nSummarize key findings from studies on the impact of climate change on ocean ecosystems.\nIdentify research gaps in the field of quantum cryptography.\nFind papers on the effectiveness of online learning platforms for STEM subjects.\nSummarize key findings from studies on the relationship between sleep deprivation and immune function.\nIdentify research gaps in the field of human-computer collaboration.\nFind papers on the impact of noise pollution on cognitive function.\nSummarize key findings from studies on the effectiveness of different obesity treatment programs.\nIdentify research gaps in the field of energy efficiency.\nSpecific Research Question Requests\nCan AI be used to develop personalized learning experiences for students?\nWhat is the impact of deforestation on climate change?\nHow effective are telemedicine services in rural areas?\nWhat are the ethical implications of using artificial intelligence in autonomous weapons?\nCan wearable devices be used to monitor and prevent falls in elderly populations?\nHow does social media influence political participation?\nWhat is the role of gut microbiota in the development of obesity?\nCan machine learning be used to predict natural disasters?\nHow can we improve access to clean water and sanitation in developing countries?\nWhat are the long-term effects of video game playing on children's cognitive development?\nCan artificial intelligence be used to discover new drugs?\nHow can we reduce plastic pollution and promote circular economy?\nWhat is the impact of sleep deprivation on mental health?\nHow can we promote sustainable tourism?\nWhat are the potential benefits and risks of using human enhancement technologies?\n"
  },
  {
    "path": "pyopenagi/data/agent_tasks/example/cocktail_mixlogist_task.txt",
    "content": "Create a cocktail for a summer garden party. Guests enjoy refreshing, citrusy flavors. Available ingredients include vodka, gin, lime, lemon, mint, and various fruit juices.\nDevelop a non-alcoholic drink for a health-conscious brunch. Focus on fresh fruits and vegetables. Avoid added sugars and artificial sweeteners.\nDesign a strong, smoky cocktail for a whiskey lover. Incorporate bold flavors like mezcal, chipotle, and lime.\nCreate a festive mocktail for a children's birthday party. Use bright colors and fun garnishes. Avoid caffeine and alcohol.\nDevelop a romantic, after-dinner drink. Focus on rich, velvety textures and sweet, indulgent flavors.\nCreate a refreshing cocktail for a beach day. Use light, tropical flavors and incorporate coconut or pineapple.\nDesign a low-calorie, high-protein cocktail for a fitness enthusiast. Use protein powder and natural sweeteners.\nDevelop a sophisticated aperitif for a formal dinner party. Use classic ingredients and emphasize balance.\nCreate a spicy margarita with a unique twist. Use fresh jalapeños or other chili peppers.\nDesign a non-alcoholic drink inspired by Asian flavors. Use ginger, lemongrass, and other aromatic ingredients.\nCreate a classic martini with a contemporary twist. Experiment with different vermouths and garnishes.\nDevelop a refreshing mocktail perfect for a hot summer day. Incorporate cucumber, mint, and citrus flavors.\nDesign a cocktail with unexpected flavor combinations. Consider using ingredients like lavender, saffron, or edible flowers.\nCreate a festive punch for a large gathering. Focus on easy-to-make and crowd-pleasing flavors.\nDevelop a non-alcoholic drink for a pregnant woman. Avoid alcohol and caffeine, while emphasizing flavor and refreshment.\nCreate a cocktail inspired by a specific country or region. Use traditional ingredients and flavors.\nDesign a mocktail that highlights seasonal fruits and vegetables.\nDevelop a cocktail perfect for a cozy night in. Focus on warm, comforting flavors like cinnamon and nutmeg.\nCreate a low-sugar cocktail for a diabetic guest. Use natural sweeteners and focus on flavor.\nDesign a non-alcoholic drink with a spicy kick. Use ginger, chili peppers, or other warming spices.\nCreate a cocktail that showcases a specific spirit or liqueur.\nDevelop a mocktail inspired by a classic cocktail.\nDesign a cocktail perfect for a brunch. Incorporate sparkling wine or champagne.\nCreate a non-alcoholic drink with a creamy texture. Use coconut milk, almond milk, or other plant-based alternatives.\nDevelop a cocktail with a balance of sweet, sour, and bitter flavors.\nCreate a festive mocktail for New Year's Eve. Use sparkling ingredients and glamorous garnishes.\nDesign a cocktail perfect for a bonfire. Incorporate smoky flavors and warm spices.\nCreate a non-alcoholic drink with a strong herbal flavor. Use ingredients like rosemary, thyme, or basil.\nDevelop a cocktail with a unique presentation. Consider using edible glassware or unusual garnishes.\nCreate a mocktail perfect for a baby shower. Use soft, pastel colors and gentle flavors.\nDesign a cocktail inspired by a famous painting or piece of art.\nDevelop a non-alcoholic drink with a strong coffee flavor. Use cold brew or espresso as a base.\nCreate a cocktail perfect for a Halloween party. Use spooky ingredients and eerie garnishes.\nDesign a mocktail with a tropical twist. Use exotic fruits and bright colors.\nDevelop a cocktail perfect for a sports game. Use refreshing and easy-to-drink ingredients.\nCreate a non-alcoholic drink with a chocolatey flavor. Use cocoa powder, chocolate syrup, or chocolate-flavored ingredients.\nDesign a cocktail perfect for a Valentine's Day date night. Use romantic ingredients and aphrodisiacs.\nCreate a mocktail with a strong citrus flavor. Use grapefruit, lemon, or lime as the main ingredient.\nDevelop a cocktail with a smoky flavor profile. Use mezcal, scotch, or other smoky spirits.\nCreate a non-alcoholic drink with a floral flavor. Use rose water, elderflower, or other floral extracts.\nDesign a cocktail perfect for a camping trip. Use simple ingredients and easy preparation methods.\nCreate a mocktail with a strong ginger flavor. Use fresh ginger, ginger beer, or ginger syrup.\nDevelop a cocktail with a balance of sweet and savory flavors.\nCreate a festive mocktail for a Fourth of July celebration. Use red, white, and blue ingredients.\nDesign a cocktail perfect for a rooftop party. Use refreshing and light ingredients.\nCreate a non-alcoholic drink with a strong mint flavor. Use fresh mint leaves and mint syrup.\nDevelop a cocktail with a unique presentation. Consider using edible flowers or smoke infusion.\nCreate a mocktail perfect for a bridal shower. Use delicate flavors and elegant garnishes.\nDesign a cocktail inspired by a classic movie or TV show.\nDevelop a non-alcoholic drink with a strong pineapple flavor. Use fresh pineapple, pineapple juice, or pineapple puree.\nCreate a cocktail perfect for a pool party. Use refreshing and hydrating ingredients.\nDesign a mocktail with a strong berry flavor. Use strawberries, raspberries, or blueberries.\nDevelop a cocktail with a balance of sweet and tart flavors.\nCreate a festive mocktail for a St. Patrick's Day celebration. Use green ingredients and Irish whiskey flavors.\nDesign a cocktail perfect for a wine tasting event. Use wine-based ingredients or pair the cocktail with a specific wine.\nCreate a non-alcoholic drink with a strong coconut flavor. Use coconut milk, coconut water, or coconut cream.\nDevelop a cocktail with a unique texture, such as frothy or creamy.\nCreate a mocktail perfect for a baby shower. Use soft, pastel colors and gentle flavors.\nDesign a cocktail inspired by a specific culture or cuisine.\nDevelop a non-alcoholic drink with a strong chai flavor. Use chai tea, chai spices, or chai syrup.\nCreate a cocktail perfect for a backyard barbecue. Use refreshing and easy-to-drink ingredients.\nDesign a mocktail with a strong citrus flavor. Use grapefruit, lemon, or lime as the main ingredient.\nDevelop a cocktail with a smoky flavor profile. Use mezcal, scotch, or other smoky spirits.\nCreate a non-alcoholic drink with a floral flavor. Use rose water, elderflower, or other floral extracts.\nDesign a cocktail perfect for a camping trip. Use simple ingredients and easy preparation methods.\nCreate a mocktail with a strong ginger flavor. Use fresh ginger, ginger beer, or ginger syrup.\nDevelop a cocktail with a balance of sweet and savory flavors.\nCreate a festive mocktail for a Fourth of July celebration. Use red, white, and blue ingredients.\nDesign a cocktail perfect for a rooftop party. Use refreshing and light ingredients.\nCreate a non-alcoholic drink with a strong mint flavor. Use fresh mint leaves and mint syrup.\nDevelop a cocktail with a unique presentation. Consider using edible flowers or smoke infusion.\nCreate a mocktail perfect for a bridal shower. Use delicate flavors and elegant garnishes.\nDesign a cocktail inspired by a classic movie or TV show.\nDevelop a non-alcoholic drink with a strong pineapple flavor. Use fresh pineapple, pineapple juice, or pineapple puree.\nCreate a cocktail perfect for a pool party. Use refreshing and hydrating ingredients.\nDesign a mocktail with a strong berry flavor. Use strawberries, raspberries, or blueberries.\nDevelop a cocktail with a balance of sweet and tart flavors.\nCreate a festive mocktail for a St. Patrick's Day celebration. Use green ingredients and Irish whiskey flavors.\nDesign a cocktail perfect for a wine tasting event. Use wine-based ingredients or pair the cocktail with a specific wine.\nCreate a non-alcoholic drink with a strong coconut flavor. Use coconut milk, coconut water, or coconut cream.\nDevelop a cocktail with a unique texture, such as frothy or creamy.\nCreate a mocktail perfect for a baby shower. Use soft, pastel colors and gentle flavors.\nDesign a cocktail inspired by a specific culture or cuisine.\nDevelop a non-alcoholic drink with a strong chai flavor. Use chai tea, chai spices, or chai syrup.\nCreate a cocktail perfect for a backyard barbecue. Use refreshing and easy-to-drink ingredients.\nDesign a mocktail with a strong citrus flavor. Use grapefruit, lemon, or lime as the main ingredient.\nDevelop a cocktail with a smoky flavor profile. Use mezcal, scotch, or other smoky spirits.\nCreate a non-alcoholic drink with a floral flavor. Use rose water, elderflower, or other floral extracts.\nDesign a cocktail perfect for a camping trip. Use simple ingredients and easy preparation methods.\nCreate a mocktail with a strong ginger flavor. Use fresh ginger, ginger beer, or ginger syrup.\nDevelop a cocktail with a balance of sweet and savory flavors.\nCreate a festive mocktail for a Fourth of July celebration. Use red, white, and blue ingredients.\nDesign a cocktail perfect for a rooftop party. Use refreshing and light ingredients.\nCreate a non-alcoholic drink with a strong mint flavor. Use fresh mint leaves and mint syrup.\nDevelop a cocktail with a unique presentation. Consider using edible flowers or smoke infusion.\nCreate a mocktail perfect for a bridal shower. Use delicate flavors and elegant garnishes.\nDesign a cocktail inspired by a classic movie or TV show.\nDevelop a non-alcoholic drink with a strong pineapple flavor. Use fresh pineapple, pineapple juice, or pineapple puree.\nCreate a cocktail perfect for a pool party. Use refreshing and hydrating ingredients.\nDesign a mocktail with a strong berry flavor. Use strawberries, raspberries, or blueberries.\n"
  },
  {
    "path": "pyopenagi/data/agent_tasks/example/cook_therapist_task.txt",
    "content": "Develop a low-carb, keto-friendly dinner that is flavorful and satisfying.\nCreate a vegetarian, Mediterranean-inspired lunch packed with nutrients.\nDesign a gluten-free, dairy-free dessert that is rich and decadent.\nDevelop a spicy, Thai-inspired curry with a balance of sweet, sour, and salty flavors.\nCreate a kid-friendly, healthy snack that is high in protein and low in sugar.\nDesign a romantic, French-inspired dinner for two with a focus on aphrodisiacs.\nDevelop a vegan, high-protein breakfast that is quick and easy to prepare.\nCreate a gluten-free pizza crust that is crispy on the outside and chewy on the inside.\nDesign a low-calorie, high-fiber soup that is perfect for weight loss.\nDevelop a meal prep-friendly, healthy lunch that can be reheated easily.\nCreate a plant-based burger that is juicy and flavorful.\nDesign a dairy-free, nut-free ice cream that is creamy and indulgent.\nDevelop a spicy, Mexican-inspired dish that is perfect for a party.\nCreate a gluten-free, one-pot pasta dish that is comforting and satisfying.\nDesign a low-sodium, heart-healthy dinner for two.\nDevelop a kid-friendly, picky-eater approved meal that is packed with vegetables.\nCreate a vegan, chocolate dessert that is rich and fudgy.\nDesign a high-protein, low-carb smoothie that is perfect for breakfast or a snack.\nDevelop a gluten-free, dairy-free pancakes recipe that is fluffy and delicious.\nCreate a budget-friendly, family-friendly dinner that is easy to make.\nDevelop a paleo-friendly, whole30 compliant dinner.\nCreate a low-FODMAP, gluten-free, dairy-free dessert.\nDesign a high-protein, low-fat snack for weight management.\nDevelop a vegetarian, Asian-inspired stir-fry with a variety of textures.\nCreate a kid-friendly, lunchbox-friendly meal with hidden vegetables.\nDesign a diabetic-friendly, low-glycemic index dessert.\nDevelop a seafood-based dish with bold, Mediterranean flavors.\nCreate a gluten-free, dairy-free pizza crust using cauliflower.\nDesign a plant-based, protein-rich bowl meal for lunch or dinner.\nDevelop a quick and easy, one-pan dinner for busy weeknights.\nCreate a low-sodium, heart-healthy soup packed with flavor.\nDesign a high-fiber, gut-friendly breakfast with probiotics.\nDevelop a vegan, chocolate-free dessert that is equally indulgent.\nCreate a kid-friendly, picky-eater approved pasta dish.\nDesign a low-carb, high-fat snack that is portable and satisfying.\nDevelop a gluten-free, dairy-free pancakes with a fluffy texture.\nCreate a budget-friendly, family-friendly meal using pantry staples.\nDesign a vegetarian, Mexican-inspired dish with bold flavors.\nDevelop a high-protein, low-carb smoothie bowl with toppings.\nCreate a gluten-free, dairy-free ice cream alternative using frozen bananas.\nDevelop a low-sodium, heart-healthy stir-fry with Asian-inspired flavors.\nCreate a vegan, gluten-free, high-protein pasta dish using lentil pasta.\nDesign a dairy-free, nut-free, chocolate-based dessert.\nDevelop a keto-friendly, high-fat breakfast with avocado as a base.\nCreate a vegetarian, Mexican-inspired chili with a smoky flavor.\nDesign a gluten-free, dairy-free pancakes using almond flour.\nDevelop a low-carb, high-protein snack bar using protein powder.\nCreate a kid-friendly, healthy lunchbox meal with hummus and fresh vegetables.\nDesign a vegan, creamy soup without dairy or cream.\nDevelop a gluten-free, dairy-free pizza crust using coconut flour.\nCreate a Mediterranean-inspired salad with grilled chicken or tofu.\nDesign a low-sugar, high-fiber dessert using fruit as a sweetener.\nDevelop a pescatarian, seafood-based chowder with a creamy texture.\nCreate a kid-friendly, picky-eater approved smoothie with hidden vegetables.\nDesign a low-carb, high-fat breakfast with eggs as the main ingredient.\nDevelop a vegan, gluten-free, high-protein energy balls.\nCreate a Mediterranean-inspired grain bowl with a variety of toppings.\nDesign a dairy-free, nut-free ice cream alternative using coconut milk.\nDevelop a low-sodium, heart-healthy soup with a bold flavor profile.\nCreate a kid-friendly, healthy lunchbox meal with leftovers.\nDevelop a low-carb, high-protein breakfast smoothie bowl with chia seeds.\nCreate a vegetarian, Indian-inspired lentil curry with coconut milk.\nDesign a gluten-free, dairy-free, chocolate avocado mousse.\nDevelop a keto-friendly, high-fat snack with bacon and cheese.\nCreate a kid-friendly, healthy lunchbox meal with leftover chicken.\nDesign a diabetic-friendly, low-glycemic index fruit salad with protein.\nDevelop a pescatarian, seafood-based paella with saffron rice.\nCreate a gluten-free, dairy-free pancakes with coconut oil.\nDesign a plant-based, protein-rich buddha bowl with quinoa.\nDevelop a quick and easy, one-pan chicken and vegetable dinner.\nCreate a low-sodium, heart-healthy grilled salmon with roasted vegetables.\nDesign a high-fiber, gut-friendly smoothie with spinach and berries.\nDevelop a vegan, chocolate-free dessert using dates and nuts.\nCreate a kid-friendly, picky-eater approved pizza with healthy toppings.\nDesign a low-carb, high-fat snack with avocado and smoked salmon.\nDevelop a gluten-free, dairy-free pancakes with coconut milk and blueberries.\nCreate a budget-friendly, family-friendly pasta dish with ground turkey.\nDesign a vegetarian, Mexican-inspired enchiladas with a spicy sauce.\nDevelop a high-protein, low-carb breakfast frittata with vegetables.\nCreate a gluten-free, dairy-free ice cream alternative using frozen bananas and cacao.\nDevelop a low-carb, high-protein lunch salad with grilled shrimp.\nCreate a vegetarian, Indian-inspired chickpea curry with spinach.\nDesign a gluten-free, dairy-free, no-bake cheesecake with fruit topping.\nDevelop a keto-friendly, high-fat snack with almond butter and celery.\nCreate a kid-friendly, healthy lunchbox meal with turkey and cheese roll-ups.\nDesign a diabetic-friendly, low-glycemic index Greek yogurt parfait.\nDevelop a pescatarian, seafood-based soup with clams and mussels.\nCreate a gluten-free, dairy-free pancakes with chia seeds and maple syrup.\nDesign a plant-based, protein-rich power bowl with brown rice.\nDevelop a quick and easy, one-pan salmon with roasted asparagus.\nCreate a low-sodium, heart-healthy lentil soup with vegetables.\nDesign a high-fiber, gut-friendly smoothie with flaxseed and probiotics.\nDevelop a vegan, chocolate-free dessert using avocado and cocoa powder.\nCreate a kid-friendly, picky-eater approved chicken nuggets with sweet potato fries.\nDesign a low-carb, high-fat snack with hard-boiled eggs and avocado.\nDevelop a gluten-free, dairy-free pancakes with coconut flour and almond milk.\nCreate a budget-friendly, family-friendly chili with ground beef.\nDesign a vegetarian, Mexican-inspired burrito bowl with black beans.\nDevelop a high-protein, low-carb breakfast omelet with spinach and feta.\nCreate a gluten-free, dairy-free ice cream alternative using frozen berries and coconut cream.\n"
  },
  {
    "path": "pyopenagi/data/agent_tasks/example/creation_agent_task.txt",
    "content": "Create an Instagram post: Image of a person using a new tech gadget, text highlighting its key features and benefits.\nDesign a Facebook ad: Image of a delicious meal, text emphasizing taste, freshness, and affordability.\nDevelop a Twitter post: Image of a striking natural landscape, text inspiring travel and adventure.\nCreate an Instagram story: Image of a fitness enthusiast doing a challenging workout, text motivating viewers to exercise.\nDesign a Facebook cover photo: Image of a bustling city skyline, text representing a dynamic and innovative company.\nDevelop a Twitter header: Image of a serene beach, text promoting relaxation and wellness.\nCreate an Instagram post: Image of a fashion model wearing the latest collection, text emphasizing style and luxury.\nDesign a Facebook ad: Image of a family enjoying a product, text highlighting its benefits for the whole family.\nDevelop a Twitter post: Image of a company logo with a vibrant color scheme, text conveying a strong brand message.\nCreate an Instagram post: Image of people volunteering for a cause, text inspiring viewers to give back.\nDesign a Facebook cover photo: Image of a diverse group of people, text promoting inclusivity and equality.\nDevelop a Twitter post: Image of a climate change-related issue, text calling for action and awareness.\nCreate an Instagram post: Image of festive decorations, text wishing followers a happy holiday.\nDesign a Facebook ad: Image of a gift wrapped in colorful paper, text promoting holiday sales.\nDevelop a Twitter post: Image of a traditional holiday dish, text sharing a holiday recipe.\nCreate an Instagram post: Image of a minimalist design, text conveying a powerful message.\nDesign a Facebook cover photo: Image using only black and white, text creating a strong visual impact.\nDevelop a Twitter post: Image with a surprising twist, text generating curiosity.\nCreate an Instagram post: Image in a square format, text maximizing impact in limited space.\nDesign a Facebook cover photo: Image optimizing for desktop and mobile views, text adaptable to different screen sizes.\nDevelop a Twitter post: Image and text fitting within character limits, conveying a clear message.\nCreate an Instagram post: Image of an influencer using a product, text highlighting the influencer's endorsement.\nDesign a Facebook cover photo: Image of an influencer and brand together, text emphasizing the partnership.\nDevelop a Twitter post: Image of an influencer sharing a product, text encouraging followers to try it.\nCreate an Instagram post: Image conveying empathy and understanding, text apologizing for a mistake.\nDesign a Facebook cover photo: Image representing company values, text reassuring customers of commitment.\nDevelop a Twitter post: Image symbolizing transparency, text acknowledging a problem and outlining solutions.\nCreate an Instagram post: Image showcasing user-generated content, text thanking followers for sharing.\nDesign a Facebook cover photo: Image featuring a collage of user-submitted photos, text encouraging participation.\nDevelop a Twitter post: Image highlighting a standout user-generated post, text praising the creator.\nCreate an Instagram post featuring a behind-the-scenes look at product creation, with text emphasizing craftsmanship and attention to detail.\nDesign a Facebook cover photo showcasing a diverse team collaborating on a project, with text promoting teamwork and innovation.\nDevelop a Twitter post featuring a customer testimonial, with text highlighting product satisfaction and loyalty.\nCreate an Instagram post featuring a limited-time offer, with text creating urgency and excitement.\nDesign a Facebook cover photo showcasing a global map, with text emphasizing the company's international reach.\nDevelop a Twitter post featuring a thought-provoking question related to the industry, with text encouraging engagement and discussion.\nCreate an Instagram post featuring a before-and-after transformation, with text highlighting product efficacy.\nDesign a Facebook cover photo showcasing a charity partnership, with text emphasizing corporate social responsibility.\nDevelop a Twitter post featuring a user-generated content highlight, with text thanking the customer and encouraging others to share.\nCreate an Instagram post featuring a product comparison chart, with text explaining the benefits of choosing the company's product.\nDesign a Facebook cover photo showcasing a company milestone, with text celebrating achievements and thanking customers.\nDevelop a Twitter post featuring an industry award or recognition, with text expressing gratitude and sharing the honor.\nCreate an Instagram post featuring a seasonal product, with text emphasizing its relevance to the current time of year.\nDesign a Facebook cover photo showcasing a customer event or gathering, with text fostering a sense of community.\nDevelop a Twitter post featuring a fun fact about the company or product, with text engaging the audience with trivia.\nCreate an Instagram post featuring a product bundle or package deal, with text highlighting the value proposition.\nDesign a Facebook cover photo showcasing a company's commitment to sustainability, with text emphasizing eco-friendly practices.\nDevelop a Twitter post featuring a customer complaint response, with text demonstrating excellent customer service and problem-solving.\nCreate an Instagram post featuring a product giveaway or contest, with text generating excitement and encouraging participation.\nDesign a Facebook cover photo showcasing a company's core values, with text inspiring employees and customers.\nDevelop a Twitter post featuring a company blog post or article, with text summarizing key points and encouraging reading.\nCreate an Instagram post featuring a product demonstration video, with text highlighting key features and benefits.\nDesign a Facebook cover photo showcasing a company's office or workspace culture, with text promoting a positive work environment.\nDevelop a Twitter post featuring a company's involvement in a local community event, with text emphasizing corporate citizenship.\nCreate an Instagram post featuring a customer success story, with text inspiring potential customers and building trust.\nDesign a Facebook cover photo showcasing a company's vision for the future, with text inspiring employees and customers.\nDevelop a Twitter post featuring a company's response to a current trend or news event, with text demonstrating relevance and engagement.\nDesign a Facebook cover photo showcasing a company milestone, with text celebrating achievements and thanking customers.\nDevelop a Twitter post featuring an industry award or recognition, with text expressing gratitude and sharing the honor.\nCreate an Instagram post featuring a seasonal product, with text emphasizing its relevance to the current time of year.\nDesign a Facebook cover photo showcasing a customer event or gathering, with text fostering a sense of community.\nDevelop a Twitter post featuring a fun fact about the company or product, with text engaging the audience with trivia.\nCreate an Instagram post featuring a product bundle or package deal, with text highlighting the value proposition.\nDesign a Facebook cover photo showcasing a company's commitment to sustainability, with text emphasizing eco-friendly practices.\nDevelop a Twitter post featuring a customer complaint response, with text demonstrating excellent customer service and problem-solving.\nCreate an Instagram post featuring a product giveaway or contest, with text generating excitement and encouraging participation.\nDesign a Facebook cover photo showcasing a company's core values, with text inspiring employees and customers.\nDevelop a Twitter post featuring a company blog post or article, with text summarizing key points and encouraging reading.\nCreate an Instagram post featuring a product demonstration video, with text highlighting key features and benefits.\nDesign a Facebook cover photo showcasing a company's office or workspace culture, with text promoting a positive work environment.\nDevelop a Twitter post featuring a company's involvement in a local community event, with text emphasizing corporate citizenship.\nCreate an Instagram post featuring a customer success story, with text inspiring potential customers and building trust.\nDesign a Facebook cover photo showcasing a company's vision for the future, with text inspiring employees and customers.\nDevelop a Twitter post featuring a company's response to a current trend or news event, with text demonstrating relevance and engagement.\nCreate an Instagram post featuring a product giveaway or contest, with text generating excitement and encouraging participation.\nDesign a Facebook cover photo showcasing a company's core values, with text inspiring employees and customers.\nDevelop a Twitter post featuring a company blog post or article, with text summarizing key points and encouraging reading.\nCreate an Instagram post featuring a product demonstration video, with text highlighting key features and benefits.\nDesign a Facebook cover photo showcasing a company's office or workspace culture, with text promoting a positive work environment.\nDevelop a Twitter post featuring a company's involvement in a local community event, with text emphasizing corporate citizenship.\nCreate an Instagram post featuring a customer success story, with text inspiring potential customers and building trust.\nDesign a Facebook cover photo showcasing a company's vision for the future, with text inspiring employees and customers.\nDevelop a Twitter post featuring a company's response to a current trend or news event, with text demonstrating relevance and engagement.\nCreate an Instagram post featuring a product giveaway or contest, with text generating excitement and encouraging participation.\nDesign a Facebook cover photo showcasing a company's core values, with text inspiring employees and customers.\nDevelop a Twitter post featuring a company blog post or article, with text summarizing key points and encouraging reading.\nCreate an Instagram post featuring a product demonstration video, with text highlighting key features and benefits.\nDesign a Facebook cover photo showcasing a company's office or workspace culture, with text promoting a positive work environment.\nDevelop a Twitter post featuring a company's involvement in a local community event, with text emphasizing corporate citizenship.\nCreate an Instagram post featuring a customer success story, with text inspiring potential customers and building trust.\nDesign a Facebook cover photo showcasing a company's vision for the future, with text inspiring employees and customers.\nDevelop a Twitter post featuring a company's response to a current trend or news event, with text demonstrating relevance and engagement.\nCreate an Instagram post featuring a product giveaway or contest, with text generating excitement and encouraging participation.\nDesign a Facebook cover photo showcasing a company's core values, with text inspiring employees and customers.\nDevelop a Twitter post featuring a company blog post or article, with text summarizing key points and encouraging reading.\nCreate an Instagram post featuring a product demonstration video, with text highlighting key features and benefits.\nDesign a Facebook cover photo showcasing a company's office or workspace culture, with text promoting a positive work environment.\nDevelop a Twitter post featuring a company's involvement in a local community event, with text emphasizing corporate citizenship.\nCreate an Instagram post featuring a customer success story, with text inspiring potential customers and building trust.\nDesign a Facebook cover photo showcasing a company's vision for the future, with text inspiring employees and customers.\n"
  },
  {
    "path": "pyopenagi/data/agent_tasks/example/fashion_stylist_task.txt",
    "content": "Design a custom tuxedo for a slender man with a preference for classic styles, incorporating a modern twist such as velvet lapels or a slim-fit cut.\nCreate a high-end evening gown for a plus-size woman with a curvy figure, emphasizing elegance and sophistication through intricate beading and rich fabric choices like silk or taffeta.\nDevelop a red carpet look for a young actress with a petite frame, focusing on a bold and dramatic silhouette, incorporating unexpected elements like feathers or metallic accents.\nDesign a wedding dress for a bohemian bride with a free-spirited personality, incorporating lace, floral motifs, and a flowing silhouette.\nCreate a mother-of-the-bride outfit for a woman in her 50s with an apple-shaped body, prioritizing comfort and style, using soft pastel colors and flattering draping.\nDesign a casual outfit for a teenage girl with a sporty aesthetic, incorporating athleisure elements into a fashionable look, using vibrant colors and comfortable fabrics.\nCreate a weekend outfit for a man in his 30s with a relaxed style, focusing on comfort and versatility, using denim and neutral colors as a base.\nDevelop a boho-chic outfit for a woman in her 20s with a slender build, incorporating flowy fabrics, earthy tones, and layered accessories.\nDesign a family-friendly outfit for a mother of two young children, prioritizing practicality and style, using comfortable yet stylish pieces that can be easily dressed up or down.\nCreate a festival-inspired outfit for a woman in her late 20s with a bohemian spirit, incorporating vibrant patterns, fringe, and comfortable footwear.\nDesign a power suit for a woman in her 30s with a strong professional image, focusing on a tailored fit and high-quality fabrics, incorporating modern elements like bold colors or unexpected textures.\nCreate a business casual outfit for a man in his 20s working in a creative industry, combining comfort and style, using contemporary cuts and incorporating trendy accessories.\nDevelop a work-from-home outfit for a woman in her 40s, balancing comfort and professionalism, using versatile pieces that can transition from video calls to household chores.\nDesign a uniform for a healthcare professional that prioritizes both function and style, incorporating modern design elements and using comfortable, easy-care fabrics.\nCreate a corporate attire for a woman with a petite frame, emphasizing sophistication and professionalism, using tailored cuts and high-quality fabrics.\nDesign a cyberpunk-inspired outfit for a young adult with a rebellious spirit, incorporating metallic accents, dark colors, and futuristic silhouettes.\nCreate a vintage-inspired dress for a woman in her 20s with a romantic style, using delicate fabrics, lace, and feminine details.\nDevelop a gothic-inspired outfit for a teenager with a dark aesthetic, incorporating black, leather, and edgy accessories.\nDesign a minimalist outfit for a man in his 30s with a clean and modern style, using neutral colors and simple lines.\nCreate a maximalist outfit for a woman in her 40s with a bold personality, incorporating vibrant colors, patterns, and textures.\nDesign a prom dress for a teenage girl with a curvy figure, focusing on a glamorous and sophisticated look, using sparkling fabrics and intricate details.\nCreate a Halloween costume for a family of five, based on a popular movie or TV show, incorporating group coordination and creativity.\nDevelop a maternity photoshoot outfit for a couple expecting twins, combining stylish and comfortable elements for both parents.\nDesign a costume for a Renaissance fair, focusing on historical accuracy and comfort, using natural fabrics and earthy tones.\nCreate a New Year's Eve outfit for a woman in her 20s, incorporating sparkle, glamour, and a touch of edginess.\nDesign a swimsuit for a woman with a pear-shaped body, emphasizing her waist and creating a balanced silhouette.\nCreate a workout outfit for a man with a muscular build, focusing on comfort and support, using moisture-wicking fabrics and athletic cuts.\nDevelop a winter coat for a petite woman, prioritizing warmth and style, using a flattering length and incorporating trendy details.\nDesign a jeans and t-shirt outfit for a plus-size woman, focusing on comfort and confidence, using flattering cuts and stylish accessories.\nCreate a formal gown for a tall and slender woman, emphasizing elegance and sophistication, using flowing fabrics and clean lines.\nDesign a collection inspired by the art deco movement, incorporating geometric shapes, metallic accents, and luxurious fabrics.\nCreate a line of clothing based on the concept of \"slow fashion,\" emphasizing sustainability, quality, and timeless design.\nDevelop a collection inspired by the natural world, using organic materials and incorporating elements like flora and fauna.\nDesign a line of activewear that is both functional and stylish, catering to a variety of fitness activities.\nCreate a collection of evening wear inspired by different cultures around the world, incorporating traditional elements with modern interpretations.\nDesign a line of handbags for professional women, focusing on functionality and style, incorporating high-quality materials and organizational features.\nCreate a collection of footwear for men that combines comfort and fashion, catering to different occasions and personal styles.\nDevelop a line of jewelry inspired by nature, using organic materials and delicate craftsmanship.\nDesign a collection of sunglasses that are both functional and fashionable, offering a variety of shapes and lens options.\nCreate a line of hats for women that complement different head shapes and hair styles, incorporating various materials and designs.\nDesign a collection of clothing for teenage boys who are into skateboarding and streetwear culture.\nCreate a line of maternity wear that is both stylish and comfortable, catering to the needs of modern expectant mothers.\nDevelop a collection of clothing for older women who value comfort and style, incorporating classic elements with contemporary touches.\nDesign a line of clothing for plus-size men, focusing on fit, style, and confidence-boosting designs.\nCreate a collection of clothing for people with disabilities, prioritizing accessibility, comfort, and fashion.\nDesign a costume for a character in a historical drama, researching the period accurately and incorporating authentic details.\nCreate a collection of wearable technology, combining fashion and function in innovative ways.\nDevelop a line of clothing for virtual reality experiences, considering the needs of the user and the virtual environment.\nDesign a collection of upcycled clothing, using repurposed materials to create unique and sustainable fashion pieces.\nCreate a line of gender-neutral clothing, challenging traditional gender norms and offering versatile options.\nDesign a collection of formal wear for a black-tie gala with a Hollywood Regency theme.\nCreate a line of clothing for a music festival with a psychedelic, bohemian vibe.\nDevelop a collection of bridal attire for destination weddings in tropical locations.\nDesign a line of clothing for a steampunk-themed event, incorporating gears, leather, and Victorian elements.\nCreate a collection of outfits for a masquerade ball, focusing on dramatic masks and elegant gowns.\nDesign a collection of clothing made entirely from recycled materials, exploring innovative techniques and aesthetics.\nCreate a line of adaptive clothing for people with mobility challenges, prioritizing both function and style.\nDevelop a collection of smart clothing incorporating technology for performance enhancement or data tracking.\nDesign a line of clothing for virtual and augmented reality experiences, considering the needs of the user and the digital environment.\nCreate a collection of gender-fluid clothing that challenges traditional gender norms and offers versatile options.\nDesign a line of clothing for professional women in the tech industry, combining style and comfort with practicality.\nCreate a collection of clothing for plus-size men who want to look stylish and confident.\nDevelop a line of clothing for teenage girls who are interested in alternative fashion and subcultures.\nDesign a collection of clothing for older men who appreciate classic styles with a modern twist.\nCreate a line of clothing for people who are environmentally conscious and prefer sustainable fashion.\nDesign a collection of clothing inspired by the concept of \"slow fashion,\" emphasizing sustainability, quality, and longevity.\nCreate a line of clothing using only natural fibers like cotton, wool, and linen.\nDevelop a collection of clothing inspired by the art and architecture of a specific city.\nDesign a line of clothing that incorporates elements of traditional craftsmanship and modern aesthetics.\nCreate a collection of clothing inspired by the concept of \"gender fluidity,\" offering versatile pieces for all body types and identities.\nDesign a line of clothing for athletes who prioritize both performance and style.\nCreate a collection of clothing for people with specific dietary restrictions or allergies, using hypoallergenic materials.\nDevelop a line of clothing for travelers who value comfort, versatility, and packing efficiency.\nDesign a collection of clothing for people who work in creative industries, emphasizing individuality and self-expression.\nCreate a line of clothing for people who are interested in cosplay and character dressing.\nDesign a collection of clothing for a black-tie wedding with a modern, minimalist aesthetic.\nCreate a line of clothing for a music festival with a country-western theme.\nDevelop a collection of clothing for a formal garden party.\nDesign a line of clothing for a Halloween party with a superhero theme.\nCreate a collection of clothing for a winter wonderland-themed event.\nDesign a collection of clothing incorporating sustainable materials and production processes.\nCreate a line of clothing inspired by the concept of \"wearable technology,\" integrating technology into fashion pieces.\nDevelop a collection of clothing that focuses on inclusivity and diversity, catering to a wide range of body types and ethnicities.\nDesign a line of clothing inspired by the concept of \"capsule wardrobe,\" offering versatile pieces that can be mixed and matched.\nCreate a collection of clothing that incorporates elements of traditional craftsmanship and modern technology.\nDesign a collection of clothing using only a limited color palette of neutrals.\nCreate a line of clothing inspired by the art of origami, incorporating folded and layered elements.\nDevelop a collection of clothing using only recycled materials.\nDesign a line of clothing inspired by the concept of \"zero waste,\" minimizing material waste during production.\nCreate a collection of clothing inspired by the beauty of imperfection, embracing unique textures and irregularities.\nDesign a collection of clothing inspired by the concept of \"slow fashion,\" emphasizing sustainability, quality, and longevity.\nCreate a line of clothing using only natural fibers like cotton, wool, and linen.\nDevelop a collection of clothing inspired by the art and architecture of a specific city.\nDesign a line of clothing that incorporates elements of traditional craftsmanship and modern aesthetics.\nCreate a collection of clothing inspired by the concept of \"gender fluidity,\" offering versatile pieces for all body types and identities.\nDesign a collection of clothing inspired by the concept of \"wearable technology,\" integrating technology into fashion pieces.\nDevelop a collection of clothing that focuses on inclusivity and diversity, catering to a wide range of body types and ethnicities.\nDesign a line of clothing inspired by the concept of \"capsule wardrobe,\" offering versatile pieces that can be mixed and matched.\nCreate a collection of clothing that incorporates elements of traditional craftsmanship and modern technology.\n"
  },
  {
    "path": "pyopenagi/data/agent_tasks/example/festival_card_designer_task.txt",
    "content": "Design a festival card for a vintage-themed music festival targeting young adults, with a square card size.\nCreate a psychedelic-inspired card for an electronic music festival aimed at a millennial audience, using a standard postcard size.\nDesign a minimalist card for a yoga and wellness festival targeting health-conscious adults, with a large square format.\nDevelop a boho-chic card for a camping and music festival appealing to young adults and families, using a standard postcard size.\nCreate a glamorous card for a film festival targeting a mature audience, with a large square format.\nDesign a rustic card for a country music festival appealing to middle-aged adults, using a standard postcard size.\nDevelop a futuristic card for a technology and music festival targeting young adults, with a square card size.\nCreate a tropical card for a beach music festival aimed at a young adult audience, using a standard postcard size.\nDesign a gothic card for a horror film festival targeting young adults, with a large square format.\nDevelop a whimsical card for a children's festival appealing to families, using a standard postcard size.\nDesign a festival card with a mermaid theme for a coastal music festival targeting young women.\nCreate a card with a cyberpunk aesthetic for a gaming and music festival aimed at teenagers.\nDesign a card with a floral pattern for a spring music festival targeting young adults.\nDevelop a card with a mountain landscape for a hiking and music festival appealing to outdoor enthusiasts.\nCreate a card with a starry night sky for an astronomy festival targeting families.\nDesign a card with a food truck theme for a street food festival aimed at young adults.\nDevelop a card with a circus theme for a family-friendly festival appealing to all ages.\nCreate a card with a masquerade theme for a formal gala and music festival targeting adults.\nDesign a card with a graffiti art style for an urban music festival aimed at young adults.\nDevelop a card with a vintage car theme for a classic car show and music festival appealing to middle-aged adults.\nDesign a festival card with a desert oasis theme for a electronic music festival targeting young adults.\nCreate a card with a steampunk aesthetic for a cosplay and music festival aimed at teenagers.\nDesign a card with a watercolor floral pattern for a wedding festival targeting couples.\nDevelop a card with a forest animal theme for a nature festival appealing to families.\nCreate a card with a galaxy theme for a science fiction festival targeting young adults.\nDesign a card with a carnival theme for a summer festival aimed at all ages.\nDevelop a card with a wine tasting theme for a food and wine festival appealing to adults.\nCreate a card with a rock and roll theme for a classic rock music festival targeting middle-aged adults.\nDesign a card with a tropical bird theme for a birdwatching festival aimed at nature enthusiasts.\nDevelop a card with a renaissance fair theme for a historical reenactment festival appealing to families.\nDesign a card with a superhero theme for a comic-con festival targeting young adults.\nCreate a card with a vintage typography style for a poetry and music festival aimed at adults.\nDesign a card with a chalkboard background for a farmer's market festival targeting families.\nDevelop a card with a neon lights aesthetic for an electronic dance music festival appealing to young adults.\nCreate a card with a fairytale theme for a children's storytelling festival targeting families.\nDesign a card with a jazz club atmosphere for a jazz music festival aimed at adults.\nDevelop a card with a sports theme for a sports and music festival appealing to young adults.\nCreate a card with a gothic castle theme for a fantasy literature festival targeting young adults.\nDesign a card with a underwater world theme for a marine life festival aimed at families.\nDevelop a card with a bohemian pattern for a world music festival appealing to young adults.\nDesign a card with a holographic aesthetic for a futuristic music festival targeting young adults.\nCreate a card with a vintage travel poster style for a music and camping festival aimed at young adults.\nDesign a card with a botanical illustration style for a garden party festival targeting adults.\nDevelop a card with a grunge aesthetic for a rock music festival appealing to young adults.\nCreate a card with a masquerade ball theme for a formal dance and music festival targeting adults.\nDesign a card with a pixel art style for a retro gaming festival aimed at young adults.\nDevelop a card with a harvest theme for a fall festival appealing to families.\nCreate a card with a circus big top theme for a family-friendly circus festival targeting all ages.\nDesign a card with a space exploration theme for a science fiction convention and music festival aimed at young adults.\nDevelop a card with a Moroccan pattern for a world music and dance festival appealing to adults.\nDesign a card with a cyberpunk city skyline for a futuristic technology festival targeting young adults.\nCreate a card with a vintage record player theme for a vinyl record collectors festival aimed at adults.\nDesign a card with a watercolor galaxy for a space-themed music festival targeting young adults.\nDevelop a card with a farm animal theme for a country living festival appealing to families.\nCreate a card with a gothic cathedral theme for a classical music festival targeting adults.\nDesign a card with a tropical island paradise theme for a beach party festival aimed at young adults.\nDevelop a card with a wine barrel theme for a vineyard festival appealing to adults.\nCreate a card with a graffiti art mural theme for an urban culture festival targeting young adults.\nDesign a card with a fairytale castle theme for a princess-themed children's festival aimed at young girls.\nDevelop a card with a desert cactus theme for a southwestern music festival appealing to adults.\nDesign a card with a vintage circus poster style for a retro-themed festival aimed at adults.\nCreate a card with a holographic rainbow theme for a pride festival targeting the LGBTQ+ community.\nDesign a card with a watercolor sunset over the ocean for a beach music festival aimed at young adults.\nDevelop a card with a gothic gargoyle theme for a horror-themed music festival appealing to young adults.\nCreate a card with a fairytale forest theme for a fantasy literature festival targeting young adults.\nDesign a card with a neon graffiti art style for an urban street festival aimed at young adults.\nDevelop a card with a vintage typewriter theme for a writer's festival appealing to adults.\nCreate a card with a cosmic astronaut theme for a space-themed music festival targeting young adults.\nDesign a card with a watercolor floral wreath for a garden party festival aimed at adults.\nDevelop a card with a steampunk airship theme for a steampunk convention and music festival appealing to young adults.\nDesign a card with a psychedelic mushroom theme for a rave festival aimed at young adults.\nCreate a card with a vintage typewriter and quill pen theme for a literary festival appealing to adults.\nDesign a card with a watercolor mountain range for a hiking and camping festival aimed at young adults.\nDevelop a card with a gothic vampire theme for a horror-themed music festival appealing to young adults.\nCreate a card with a fairytale princess theme for a children's ball aimed at young girls.\nDesign a card with a neon palm tree theme for a tropical music festival aimed at young adults.\nDevelop a card with a wine grapevine theme for a harvest festival appealing to adults.\nCreate a card with a graffiti-covered subway car theme for an urban music festival aimed at young adults.\nDesign a card with a watercolor mermaid theme for a beach-themed music festival aimed at young adults.\nDevelop a card with a steampunk robot theme for a technology and music festival appealing to young adults.\nDesign a card with a psychedelic galaxy theme for a space-themed music festival aimed at young adults.\nCreate a card with a vintage book cover theme for a literary festival appealing to adults.\nDesign a card with a watercolor forest scene for a nature and music festival aimed at young adults.\nDevelop a card with a gothic werewolf theme for a horror-themed music festival appealing to young adults.\nCreate a card with a fairytale dragon theme for a fantasy literature festival targeting young adults.\nDesign a card with a neon cityscape theme for an urban music festival aimed at young adults.\nDevelop a card with a wine glass and grapes theme for a wine tasting festival appealing to adults.\nCreate a card with a graffiti-covered wall theme for an urban art festival aimed at young adults.\nDesign a card with a watercolor underwater scene for a marine life festival aimed at families.\nDevelop a card with a steampunk airship battle theme for a steampunk convention and music festival appealing to young adults.\nDesign a festival card for a music festival with a psychedelic, space-themed atmosphere.\nCreate a card for a music festival with a bohemian, nature-inspired vibe.\nDesign a card for a music festival with a futuristic, cyberpunk aesthetic.\nCreate a card for a music festival with a vintage, retro feel.\nDesign a card for a music festival with a tropical, beach party atmosphere.\nCreate a card for a music festival with a grunge, underground scene vibe.\nDesign a card for a music festival with a luxurious, upscale feel.\nCreate a card for a music festival with a family-friendly, carnival atmosphere.\nDesign a card for a music festival with a minimalist, modern aesthetic.\nCreate a card for a music festival with a magical, enchanted forest theme.\n"
  },
  {
    "path": "pyopenagi/data/agent_tasks/example/fitness_trainer_task.txt",
    "content": "Create a workout plan for a busy professional aiming to lose 10 pounds in 3 months.\nDesign a strength training routine for a beginner focusing on building muscle mass.\nDevelop a cardio-based workout plan for someone recovering from a knee injury.\nCreate a balanced workout routine for a vegetarian athlete training for a marathon.\nDesign a home workout plan for a mother of two with limited equipment.\nDevelop a post-pregnancy workout plan focusing on core strength and pelvic floor health.\nCreate a workout plan for a senior citizen aiming to improve balance and flexibility.\nDesign a high-intensity interval training (HIIT) workout for someone looking to burn calories fast.\nDevelop a bodyweight workout plan for a traveler with no access to a gym.\nCreate a workout plan for an office worker suffering from chronic back pain.\nDesign a workout plan for a golfer aiming to improve swing power and flexibility.\nDevelop a strength training routine for a rock climber focusing on upper body strength.\nCreate a cardio workout plan for a swimmer looking to increase endurance.\nDesign a workout plan for a dancer aiming to improve strength, flexibility, and balance.\nDevelop a strength training routine for a tennis player focusing on core stability and power.\nCreate a workout plan for a cyclist aiming to improve leg strength and endurance.\nDesign a workout plan for a basketball player focusing on agility and explosiveness.\nDevelop a workout plan for a soccer player aiming to improve speed and stamina.\nCreate a workout plan for a volleyball player focusing on jumping power and arm strength.\nDesign a workout plan for a martial artist aiming to improve strength, flexibility, and balance.\nCreate a beginner-friendly yoga workout plan for stress relief.\nDesign a modified workout plan for someone with arthritis in their hands.\nDevelop a low-impact workout plan for someone with plantar fasciitis.\nCreate a workout plan for an overweight individual starting their fitness journey.\nDesign a workout plan for a highly fit individual looking to build muscle and strength.\nDevelop a workout plan for someone with asthma focusing on cardio and strength.\nCreate a workout plan for someone with diabetes focusing on blood sugar control.\nDesign a workout plan for someone with osteoporosis focusing on bone health.\nDevelop a workout plan for someone with high blood pressure focusing on endurance.\nCreate a workout plan for someone with vertigo focusing on balance and stability.\nCreate a meal plan for a vegan athlete training for a triathlon.\nCreate a workout plan for a vegan bodybuilder aiming to increase muscle mass.\nDesign a workout plan for a person with lactose intolerance focusing on calcium intake.\nDevelop a workout plan for a competitive eater looking to improve overall fitness.\nCreate a workout plan for a fashion model aiming to tone and lengthen muscles.\nDesign a workout plan for a professional gamer to improve posture and reduce back pain.\nDevelop a workout plan for a firefighter aiming to improve cardiovascular endurance.\nCreate a workout plan for a police officer focusing on upper body strength and agility.\nDesign a workout plan for a construction worker aiming to prevent injuries.\nDevelop a workout plan for a chef to improve stamina and balance.\nCreate a workout plan for a software engineer to combat sedentary lifestyle.\nCreate a workout plan using only resistance bands for a home workout.\nDesign a bodyweight workout plan for a park setting.\nDevelop a workout plan using dumbbells for a home gym.\nCreate a workout plan using a kettlebell for full-body strength training.\nDesign a workout plan using a treadmill and elliptical for cardio.\nDevelop a workout plan using a swimming pool for water resistance training.\nCreate a workout plan using a yoga mat for flexibility and core strength.\nDesign a workout plan using a gym with full equipment access.\nDevelop a workout plan using a small apartment with limited space.\nCreate a workout plan using a hotel gym with basic equipment.\nCreate a 30-day ab challenge workout plan.\nDesign a 4-week weight loss challenge workout plan.\nDevelop a 6-week muscle building challenge workout plan.\nCreate a 12-week half marathon training plan.\nDesign a full-body circuit workout for maximum calorie burn.\nDevelop a plyometric workout for improving explosive power.\nCreate a yoga flow sequence for flexibility and relaxation.\nDesign a pilates workout for core strength and stability.\nDevelop a barre workout for toning and lengthening muscles.\nCreate a TRX suspension trainer workout for full-body strength.\nCreate a prenatal workout plan focusing on safety and well-being.\nDesign a postpartum workout plan for recovering mothers.\nDevelop a workout plan for teenagers to improve fitness and confidence.\nCreate a workout plan for people with disabilities focusing on accessibility.\nDesign a workout plan for athletes recovering from injuries.\nDevelop a workout plan for firefighters to improve strength and endurance.\nCreate a workout plan for police officers to enhance fitness and agility.\nDesign a workout plan for military personnel to build physical resilience.\nDevelop a workout plan for healthcare workers to manage stress and fatigue.\nCreate a workout plan for teachers to improve energy and focus.\nCreate a workout plan to reduce anxiety and stress.\nDesign a workout plan to improve sleep quality.\nDevelop a workout plan to boost mood and energy levels.\nCreate a workout plan to enhance focus and concentration.\nDesign a workout plan to build self-confidence and body positivity.\nDevelop a workout plan to manage symptoms of depression.\nCreate a workout plan to improve overall mental well-being.\nDesign a workout plan to increase resilience and adaptability.\nDevelop a workout plan to enhance creativity and problem-solving skills.\nCreate a workout plan to cultivate mindfulness and presence.\nCreate a workout plan that can be followed using a fitness tracker.\nDesign a workout plan that incorporates virtual reality for an immersive experience.\nDevelop a workout plan that uses wearable technology to monitor performance.\nCreate a workout plan that can be streamed live online for group fitness.\nCreate a workout plan that uses fitness apps to track progress and provide feedback.\nDesign a workout plan that integrates smart home devices for a connected fitness experience.\nDevelop a workout plan that utilizes gamification elements to enhance motivation.\nCreate a workout plan that incorporates virtual fitness coaches for personalized guidance.\nDesign a workout plan that uses heart rate monitors to optimize workout intensity.\nCreate a workout plan for individuals with chronic fatigue syndrome.\nDesign a workout plan for people with multiple sclerosis.\nDevelop a workout plan for individuals with Parkinson's disease.\nCreate a workout plan for people with fibromyalgia.\nDesign a workout plan for individuals with rheumatoid arthritis.\nCreate a workout plan for a night shift worker to optimize energy levels.\nDesign a workout plan for a college student with a busy schedule.\nDevelop a workout plan for a frequent traveler to maintain fitness on the road.\nCreate a workout plan for a busy executive to fit exercise into a demanding lifestyle.\nDesign a workout plan for a retired individual looking to stay active and healthy.\n"
  },
  {
    "path": "pyopenagi/data/agent_tasks/example/game_agent_task.txt",
    "content": "Recommend a relaxing puzzle game for Nintendo Switch, suitable for a casual player.\nSuggest a challenging action RPG for PC, targeting a hardcore gamer seeking a deep story.\nFind a multiplayer FPS for Xbox One that offers intense, competitive gameplay.\nRecommend a cooperative adventure game for PS4, ideal for a group of friends wanting a fun experience.\nSuggest a horror game for PC, suitable for someone who enjoys jump scares and intense atmosphere.\nFind a strategy game for Nintendo Switch, targeting a player looking for a deep, tactical experience.\nRecommend a racing game for Xbox One, suitable for a player who prefers arcade-style gameplay.\nSuggest a role-playing game for PS4, ideal for a player who enjoys character customization and open worlds.\nFind a sports game for PC, targeting a player who wants a realistic simulation experience.\nRecommend a platformer for Nintendo Switch, suitable for a player looking for a challenging and rewarding experience.\nSuggest a stealth game for PC, ideal for a player who enjoys planning and execution.\nFind a simulation game for Xbox One, targeting a player interested in managing a virtual world.\nRecommend a rhythm game for PS4, suitable for a player who loves music and wants to test their reflexes.\nSuggest a fighting game for PC, ideal for a competitive player seeking fast-paced action.\nFind a casual game for Nintendo Switch, suitable for a player looking to relax and unwind.\nRecommend a survival game for Xbox One, targeting a player who enjoys resource management and exploration.\nSuggest a puzzle-platformer for PS4, ideal for a player who likes challenges and brain-teasers.\nFind an open-world game for PC, targeting a player who wants endless possibilities and exploration.\nRecommend a multiplayer online battle arena (MOBA) for Nintendo Switch, suitable for a competitive player looking for fast-paced action.\nSuggest a massively multiplayer online role-playing game (MMORPG) for Xbox One, ideal for a player who enjoys social interaction and progression.\nFind a visual novel for PS4, targeting a player who enjoys storytelling and character development.\nRecommend a indie game for PC, suitable for a player looking for unique and innovative experiences.\nSuggest a party game for Nintendo Switch, ideal for a group of friends looking for fun and laughter.\nFind a card game for Xbox One, targeting a player who enjoys strategy and competition.\nRecommend a farming simulator for PS4, suitable for a player who enjoys relaxing gameplay and building a virtual farm.\nSuggest a space simulator for PC, ideal for a player interested in exploration and scientific discovery.\nFind a point-and-click adventure game for Nintendo Switch, targeting a player who enjoys puzzles and storytelling.\nRecommend a sports management game for Xbox One, suitable for a player who enjoys strategic decision-making.\nSuggest a battle royale game for PS4, ideal for a player who enjoys fast-paced, large-scale combat.\nFind a sandbox game for PC, targeting a player who enjoys creativity and experimentation.\nRecommend a stealth-action game for Nintendo Switch, suitable for a player who enjoys combining stealth and combat.\nSuggest a turn-based strategy game for Xbox One, ideal for a player who enjoys careful planning and tactical decisions.\nFind a role-playing game with a focus on character development for PS4, targeting a player who enjoys deep storylines and choices.\nRecommend a multiplayer co-op shooter for PC, suitable for a group of friends who enjoy teamwork and action.\nSuggest a racing game with a focus on realistic simulation for Xbox One, targeting a player who enjoys high-speed competition.\nFind a sports game with a focus on arcade-style gameplay for PS4, targeting a player who enjoys fast-paced and fun action.\nRecommend a puzzle game with a focus on logic and deduction for Nintendo Switch, suitable for a player who enjoys mental challenges.\nSuggest a horror game with a focus on psychological terror for PC, targeting a player who enjoys suspense and atmosphere.\nFind a platformer with a focus on precision and timing for Xbox One, suitable for a player who enjoys challenging gameplay.\nRecommend a simulation game with a focus on building and management for PS4, targeting a player who enjoys creating and growing.\nSuggest a rhythm game with a focus on dance and movement for PC, suitable for a player who enjoys physical activity and music.\nFind a fighting game with a focus on character customization for Xbox One, targeting a player who enjoys creating unique fighters.\nRecommend a casual game with a focus on time management for Nintendo Switch, suitable for a player who enjoys multitasking and challenges.\nSuggest a survival game with a focus on crafting and survival for PS4, targeting a player who enjoys resource management and exploration.\nFind a puzzle-platformer with a focus on environmental puzzles for PC, suitable for a player who enjoys using their surroundings to solve challenges.\nRecommend an open-world game with a focus on exploration and discovery for Xbox One, targeting a player who enjoys finding hidden secrets.\nSuggest a multiplayer online battle arena (MOBA) with a focus on teamwork and strategy for PS4, targeting a player who enjoys coordinated gameplay.\nFind a massively multiplayer online role-playing game (MMORPG) with a focus on player housing and customization for PC, targeting a player who enjoys building their own space.\nRecommend a visual novel with a focus on romance and relationships for Nintendo Switch, suitable for a player who enjoys character interactions.\nSuggest an indie game with a focus on pixel art for Xbox One, targeting a player who enjoys nostalgic and retro-style games.\nRecommend a party game with a focus on physical activity for PS4, suitable for a player who enjoys energetic and interactive gameplay.\nSuggest a card game with a focus on bluffing and deception for PC, targeting a player who enjoys social deduction games.\nFind a farming simulator with a focus on animal care for Nintendo Switch, suitable for a player who enjoys building relationships with virtual animals.\nRecommend a space simulator with a focus on combat and dogfights for Xbox One, targeting a player who enjoys fast-paced action in space.\nSuggest a point-and-click adventure game with a focus on humor and comedy for PS4, targeting a player who enjoys lighthearted storytelling.\nFind a sports management game with a focus on player development for PC, targeting a player who enjoys building a successful team.\nRecommend a battle royale game with a focus on vehicles and combat for Nintendo Switch, suitable for a player who enjoys fast-paced action and strategy.\nSuggest a sandbox game with a focus on physics-based gameplay for Xbox One, targeting a player who enjoys experimentation and creativity.\nFind a stealth-action game with a focus on melee combat for PS4, targeting a player who enjoys close-quarters combat and stealth.\nRecommend a turn-based strategy game with a focus on hexagons for PC, suitable for a player who enjoys unique gameplay mechanics.\nSuggest a role-playing game with a focus on moral choices and consequences for Xbox One, targeting a player who enjoys making impactful decisions.\nFind a multiplayer co-op shooter with a focus on horror elements for PS4, suitable for a group of friends who enjoy cooperative scares.\nRecommend a racing game with a focus on drift racing for Nintendo Switch, suitable for a player who enjoys stylish and controlled driving.\nSuggest a sports game with a focus on extreme sports for PC, targeting a player who enjoys adrenaline-pumping action.\nFind a puzzle game with a focus on time travel for Xbox One, suitable for a player who enjoys mind-bending challenges.\nRecommend a horror game with a focus on survival horror for PS4, targeting a player who enjoys resource management and fear.\nSuggest a platformer with a focus on speedrunning for PC, suitable for a player who enjoys challenges and competition.\nFind a simulation game with a focus on city building for Nintendo Switch, suitable for a player who enjoys creating bustling metropolises.\nRecommend a rhythm game with a focus on vocaloid music for Xbox One, suitable for a player who enjoys Japanese pop culture.\nSuggest a fighting game with a focus on tag team battles for PS4, suitable for a player who enjoys cooperative gameplay.\nFind a casual game with a focus on puzzle solving for PC, suitable for a player who enjoys brain teasers and challenges.\nRecommend a survival game with a focus on base building for Xbox One, targeting a player who enjoys creating a fortified home.\nSuggest a puzzle-platformer with a focus on water mechanics for PS4, suitable for a player who enjoys unique gameplay elements.\nFind an open-world game with a focus on wildlife and nature for Nintendo Switch, suitable for a player who enjoys exploring the natural world.\nRecommend a multiplayer online battle arena (MOBA) with a focus on fast-paced action for Xbox One, suitable for a player who enjoys quick and intense gameplay.\nSuggest a massively multiplayer online role-playing game (MMORPG) with a focus on player-driven economies for PC, targeting a player who enjoys trading and resource management.\nFind a visual novel with a focus on mystery and suspense for Nintendo Switch, suitable for a player who enjoys solving puzzles and unraveling secrets.\nRecommend an indie game with a focus on pixel art and platforming for Xbox One, targeting a player who enjoys challenging and nostalgic gameplay.\nSuggest a party game with a focus on trivia and knowledge for PS4, suitable for a group of friends who enjoy testing their wits.\nFind a card game with a focus on deck-building for PC, targeting a player who enjoys strategic planning and customization.\nRecommend a farming simulator with a focus on fishing and animal breeding for Nintendo Switch, suitable for a player who enjoys a relaxing and immersive experience.\nSuggest a space simulator with a focus on exploration and discovery of alien life for Xbox One, targeting a player who enjoys scientific exploration.\nFind a point-and-click adventure game with a focus on time manipulation for PS4, suitable for a player who enjoys puzzles and mind-bending challenges.\nRecommend a sports management game with a focus on team chemistry and player morale for PC, targeting a player who enjoys building strong relationships within a team.\nSuggest a battle royale game with a focus on looting and scavenging for Nintendo Switch, suitable for a player who enjoys survival and resource management.\nFind a sandbox game with a focus on vehicle customization for Xbox One, targeting a player who enjoys creating unique and powerful vehicles.\nRecommend a stealth-action game with a focus on hacking and gadgets for PS4, suitable for a player who enjoys using technology to overcome challenges.\nSuggest a turn-based strategy game with a focus on diplomacy and negotiation for PC, targeting a player who enjoys social interaction and political maneuvering.\nFind a role-playing game with a focus on multiple playable characters for Xbox One, suitable for a player who enjoys experiencing different perspectives.\nRecommend a multiplayer co-op shooter with a focus on class-based roles for PS4, suitable for a group of friends who enjoy teamwork and specialization.\nSuggest a racing game with a focus on open-world exploration for PC, suitable for a player who enjoys discovering hidden routes and landmarks.\nFind a sports game with a focus on online competition and leaderboards for Nintendo Switch, suitable for a player who enjoys challenging other players.\nRecommend a puzzle game with a focus on physics-based challenges for Xbox One, suitable for a player who enjoys using logic and experimentation.\nSuggest a horror game with a focus on first-person perspective for PS4, suitable for a player who enjoys immersive and intense experiences.\nFind a platformer with a focus on speed and agility for PC, suitable for a player who enjoys fast-paced and challenging gameplay.\nRecommend a simulation game with a focus on theme park management for Nintendo Switch, suitable for a player who enjoys creating and designing attractions.\nSuggest a rhythm game with a focus on karaoke for Xbox One, suitable for a player who enjoys singing and performing.\nFind a fighting game with a focus on projectile attacks for PS4, suitable for a player who enjoys long-range combat and strategy.\nRecommend a casual game with a focus on word puzzles for PC, suitable for a player who enjoys challenging their vocabulary.\nSuggest a survival game with a focus on base defense for Xbox One, suitable for a player who enjoys strategic planning and combat.\n"
  },
  {
    "path": "pyopenagi/data/agent_tasks/example/interior_decorator_task.txt",
    "content": "I want to transform my small, dark living room into a bright and airy space. I love minimalist Scandinavian design and prefer neutral colors. Can you help me?\nMy bedroom is a disaster! Its a large room with high ceilings. I need help creating a cozy, romantic atmosphere with a touch of luxury. I like deep colors and lots of textures.\nIm looking to redesign my kitchen. Its a modern, open-concept space. I want it to be functional and stylish. I love the industrial look but with warm accents. Help me create a space where I can both cook and entertain.\nI have a small, square dining room that feels cramped. I want to create an elegant and inviting space for dinner parties. I love classic, timeless styles and prefer a neutral color palette.\nMy home office is a mess! Its a small, windowless room. I need it to be functional and inspiring. I want a modern, minimalist workspace with pops of color. Can you help me?\nI want to create a bohemian-inspired living room. I have a large, open floor plan with high ceilings. I love earthy tones, lots of plants, and global accents. Can you suggest some furniture and decor pieces?\nIm obsessed with mid-century modern design. I have a small, square living room. I want it to be stylish and functional. Can you help me find a sofa and coffee table that fit the style?\nI want to create a luxurious, spa-like bathroom. Its a large room with a soaking tub. I love neutral colors, natural materials, and plenty of candles. Can you suggest some decor items to create a relaxing atmosphere?\nIm going for a coastal cottage look in my bedroom. Its a medium-sized room with a lot of natural light. I love light blues, whites, and natural wood. Can you help me find a bed frame and nightstands that fit the style?\nI want to create a playful, colorful kids room. Its a medium-sized room with one wall painted yellow. I love animals and whimsical patterns. Can you suggest some furniture and decor that will spark their imagination?\nI want to create a dramatic living room with deep jewel tones. I have a large, open floor plan with a fireplace. I want the room to feel cozy and inviting. Can you suggest a color palette and furniture styles?\nI love the look of natural materials. I want to create a serene bedroom with lots of wood, stone, and plants. Its a medium-sized room with a bay window. Can you suggest a color palette and furniture styles?\nI want to create a bright and airy kitchen with white cabinets. I have a small, galley-style kitchen. I want it to feel spacious and modern. Can you suggest backsplash tiles and countertop materials?\nI want to create a moody dining room with black walls. Its a small, square room with a chandelier. I want it to feel elegant and sophisticated. Can you suggest furniture and decor items?\nI love the look of gold accents. I want to create a glamorous bathroom with a marble vanity. Its a large room with a walk-in shower. Can you suggest lighting and decor items to complete the look?\nI have a small living room that also needs to function as a home office. I want it to be stylish and functional. I love the industrial look but need plenty of storage. Can you help me?\nI have a narrow hallway that feels like wasted space. I want to make it more functional and visually appealing. I love modern art and minimalist decor. Can you suggest some ideas?\nI have a large, open-concept living and dining area. I want to define the spaces without making the room feel smaller. I love the bohemian style and want to incorporate lots of plants. Can you help me?\nI have a small bedroom with limited closet space. I want to maximize storage and create a calming atmosphere. I love soft colors and natural materials. Can you help me?\nI have a small, dark kitchen with outdated cabinets. I want to update the space without a complete renovation. I love white cabinets and stainless steel appliances. Can you suggest some affordable updates?\nI have a small, L-shaped living room. I want to create a cozy and inviting space for entertaining guests. I love the farmhouse style with a modern twist. Can you help me?\nMy bedroom is very small and lacks natural light. I want to create a calming and relaxing space to unwind. I prefer soft, muted colors and minimalist decor. Can you help me maximize the space?\nI have a large, open-concept kitchen and living room. I want to create a seamless flow between the two spaces. I love a modern industrial look with warm wood accents. Can you help me define the areas?\nMy dining room is rectangular and has high ceilings. I want to create a formal and elegant space for dinner parties. I prefer a classic, traditional style with a touch of luxury. Can you help me?\nI have a small, half-bath that I want to make feel more spacious and luxurious. I love marble and gold accents. Can you suggest some design ideas?\nI love the eclectic style but don't know where to start. I have a large living room with lots of natural light. I want to create a space that reflects my personality. Can you help me?\nI'm drawn to the Japanese wabi-sabi aesthetic. I have a small, minimalist bedroom. I want to create a serene and peaceful space. Can you suggest some furniture and decor pieces?\nI want to create a glamorous Hollywood Regency-inspired bedroom. I have a medium-sized room with high ceilings. I love gold accents, mirrored furniture, and plush fabrics. Can you help me?\nI'm interested in creating a sustainable and eco-friendly living space. I have a large, open-concept living and dining area. I want to use natural materials and incorporate indoor plants. Can you help me?\nI love the vintage and retro style. I have a small apartment with limited space. I want to create a stylish and functional home. Can you suggest some furniture and decor pieces?\nI have a small, open-plan kitchen and living room. I need help creating a functional layout that maximizes space. I love a clean, modern look. Can you help me?\nMy living room is often used for movie nights. I need to create a comfortable and inviting space for watching TV. I love a cozy, laid-back atmosphere. Can you help me?\nI have a large family and need a dining room that can accommodate everyone comfortably. I want a warm and inviting space for family gatherings. I prefer a classic, traditional style. Can you help me?\nI work from home and need to create a dedicated workspace in my bedroom. I want to keep the space visually appealing and clutter-free. I love a minimalist aesthetic. Can you help me?\nI have a pet and need to create a home that is both stylish and pet-friendly. I want to choose durable materials and colors that hide stains. Can you suggest some ideas?\nMy loft apartment has an open floor plan. I want to create distinct living, dining, and sleeping areas without walls. I love a modern industrial look. Can you help me?\nI have a small, windowless bathroom. I want to make it feel as spacious and bright as possible. I prefer a clean, minimalist aesthetic. Can you help me?\nMy teen's bedroom is outdated. I want to create a stylish and functional space that they will love. I'm open to different styles but want to avoid anything too childish. Can you help me?\nI have a large, formal living room that feels too stuffy. I want to create a more relaxed and inviting atmosphere. I love a mix of modern and traditional styles. Can you help me?\nMy basement is unfinished and I want to transform it into a cozy family room. I have a large, open space to work with. I love a rustic, farmhouse style. Can you help me?\nI'm drawn to the Scandinavian hygge style. I have a small apartment with limited natural light. I want to create a warm and inviting space. Can you help me?\nI love the dramatic, dark academia aesthetic. I have a medium-sized living room with high ceilings. I want to create a sophisticated and intellectual atmosphere. Can you help me?\nI'm interested in creating a minimalist, Japanese-inspired bedroom. I have a small, square room. I want to focus on functionality and simplicity. Can you help me?\nI want to create a vibrant, tropical-inspired bathroom. I have a large bathroom with a lot of natural light. I love bright colors and bold patterns. Can you help me?\nI'm drawn to the eclectic, bohemian style but want to avoid clutter. I have a large, open-concept living and dining area. I want to create a space that is both stylish and functional. Can you help me?\nI have a small kitchen with limited counter space. I need help maximizing storage and creating a more efficient workspace. I love a clean, modern look. Can you help me?\nMy living room is also used as a guest room. I need to create a space that is both comfortable for guests and stylish for everyday living. I prefer a neutral color palette. Can you help me?\nI have a large family room that gets a lot of use. I need to create a durable and kid-friendly space. I love a casual, comfortable atmosphere. Can you help me?\nI have a small balcony that I want to transform into an outdoor oasis. I have limited space to work with. I love the Mediterranean style. Can you help me?\nI have a large, open-concept living and dining area with high ceilings. I want to create a sense of intimacy and warmth. I love a mix of modern and rustic styles. Can you help me?\nMy attic space is unfinished but has potential. I want to create a cozy and inviting bedroom retreat. I love a rustic, bohemian style. Can you help me?\nMy laundry room is small and cluttered. I want to make it more functional and visually appealing. I love a clean, minimalist aesthetic. Can you help me?\nMy home office is in a corner of my bedroom. I need to create a defined workspace without sacrificing privacy. I love a modern, industrial style. Can you help me?\nMy dining room is open to the kitchen and living room. I want to create a distinct dining area without closing off the space. I love a contemporary, minimalist style. Can you help me?\nMy mudroom is small and chaotic. I need help creating a functional and organized space. I love a classic, farmhouse style. Can you help me?\nI'm drawn to the glamorous Art Deco style. I have a large living room with high ceilings. I want to create a sophisticated and luxurious atmosphere. Can you help me?\nI love the cozy, cottagecore aesthetic. I have a small, cottage-style home. I want to create a warm and inviting atmosphere. Can you help me?\nI'm interested in creating a minimalist, Scandinavian-inspired kitchen. I have a small, galley-style kitchen. I want to maximize storage and create a clean workspace. Can you help me?\nI want to create a vibrant, Moroccan-inspired bathroom. I have a medium-sized bathroom with white tiles. I love bold colors and intricate patterns. Can you help me?\nI'm drawn to the eclectic, maximalist style. I have a large, open-concept living and dining area. I want to create a visually stimulating and interesting space. Can you help me?\nI have a small apartment with limited storage space. I need help maximizing storage without sacrificing style. I love a modern, minimalist aesthetic. Can you help me?\nMy living room is used for both relaxation and entertaining. I need to create a versatile space that can accommodate different activities. I love a comfortable, casual atmosphere. Can you help me?\nI have a large, open-concept kitchen and living room with noisy appliances. I need to create a quiet and relaxing living space. I love a modern, minimalist style. Can you help me?\nMy bedroom is also used as a guest room. I need to create a space that is both comfortable for guests and functional for myself. I prefer a neutral color palette. Can you help me?\nI have a small balcony with limited space. I want to create a functional outdoor space for relaxing and entertaining. I love a cozy, urban garden style. Can you help me?\nMy basement is unfinished and I want to create a home theater. I have a large, open space to work with. I love a modern, industrial style. Can you help me?\nMy guest bedroom is rarely used. I want to create a space that is both inviting and functional for occasional guests. I prefer a minimalist, modern style. Can you help me?\nMy kitchen is outdated and lacks storage. I want to create a functional and stylish kitchen without a complete renovation. I love a classic, white kitchen look. Can you help me?\nMy dining room is too small for a large dining table. I want to create a cozy and intimate dining space. I love a rustic, farmhouse style. Can you help me?\nMy hallway is long and narrow. I want to make it feel more spacious and interesting. I love a modern, minimalist style with pops of color. Can you help me?\nI'm drawn to the romantic, French country style. I have a medium-sized bedroom with a fireplace. I want to create a cozy and elegant space. Can you help me?\nI love the edgy, industrial chic style. I have a loft apartment with exposed brick walls. I want to create a cool and modern space. Can you help me?\nI'm interested in creating a minimalist, Scandinavian-inspired living room. I have a large, open-concept space. I want to create a calm and serene atmosphere. Can you help me?\nI want to create a vibrant, tropical-inspired dining room. I have a small, square dining room with limited natural light. Can you help me?\nI'm drawn to the eclectic, boho-chic style but want to keep it refined. I have a medium-sized living room with a neutral color palette. Can you help me?\nI have a small kitchen with limited counter space. I need to find creative storage solutions. I love a clean, modern look. Can you help me?\nMy living room is used for both relaxation and entertaining. I need to create a flexible seating arrangement. I prefer a comfortable, casual atmosphere. Can you help me?\nI have a large, open-concept kitchen and living room with noise issues. I need to find ways to reduce noise pollution. I love a modern, minimalist style. Can you help me?\nMy bedroom is also a home office. I need to create a visually appealing and functional workspace. I prefer a minimalist, modern style. Can you help me?\nI have a small balcony with limited space. I want to create a functional outdoor dining area. I love a cozy, urban garden style. Can you help me?\nMy kitchen is small and outdated. I want to create a modern and functional space without a complete overhaul. I love white cabinets and stainless steel appliances. Can you help me?\nMy living room is open to the dining area and kitchen. I want to create a sense of separation without building walls. I love a minimalist, modern style. Can you help me?\nMy bedroom has slanted ceilings due to the room being in the attic. I want to create a cozy and inviting space. I love a bohemian, eclectic style. Can you help me?\nMy bathroom is small and lacks natural light. I want to create a spa-like atmosphere. I love neutral colors and natural materials. Can you help me?\nMy home office is in a spare bedroom. I want to create a dedicated workspace that is both functional and stylish. I love a modern, minimalist aesthetic. Can you help me?\nI'm drawn to the glamorous Art Deco style but want to incorporate modern elements. I have a large living room with high ceilings. Can you help me?\nI love the rustic, farmhouse style but want to avoid feeling too country. I have a medium-sized kitchen with white cabinets. Can you help me?\nI'm interested in creating a minimalist, Japanese-inspired bedroom. I have a small, square room with limited storage. Can you help me?\nI want to create a vibrant, eclectic bathroom with a Moroccan-inspired flair. I have a medium-sized bathroom with white tiles. Can you help me?\nI'm drawn to the industrial chic style but want to add warmth and texture. I have a loft apartment with exposed brick walls. Can you help me?\nI have a small apartment with limited storage space. I need to find creative ways to maximize storage in the bedroom. I love a minimalist, modern aesthetic. Can you help me?\nMy living room is used for both relaxation and entertaining. I need to create a flexible seating arrangement that can accommodate different group sizes. I prefer a comfortable, casual atmosphere. Can you help me?\nI have a large, open-concept kitchen and living room with noise issues. I need to find sound-absorbing solutions that are also stylish. I love a modern, minimalist style. Can you help me?\nMy bedroom is also a home gym. I need to create a space that is both functional for workouts and relaxing for sleep. I prefer a minimalist, modern style. Can you help me?\nI have a small balcony with limited space. I want to create a functional outdoor workspace. I love a modern, minimalist style. Can you help me?\nI have a small, dark hallway that feels cramped and cluttered. I want to create a welcoming and spacious entryway. I love a modern, minimalist style with pops of color. Can you help me?\nMy kitchen is open to the living room and I want to create a breakfast nook. I have limited space but want it to be cozy and inviting. I love a rustic, farmhouse style. Can you help me?\nMy bedroom has a vaulted ceiling and I want to create a focal point. I love a bohemian, eclectic style. Can you help me?\nMy bathroom is small and lacks storage. I want to maximize storage and create a spa-like atmosphere. I love neutral colors and natural materials. Can you help me?\nMy home office is in a spare bedroom and I want to create a soundproof workspace. I love a modern, minimalist aesthetic. Can you help me?\n"
  },
  {
    "path": "pyopenagi/data/agent_tasks/example/language_tutor_task.txt",
    "content": "Provide conversation practice for beginner level Arabic learners, focusing on basic greetings, introductions, and asking for directions.\nHelp me improve my English presentation skills by providing tips on structure, delivery, and visual aids.\nCreate a vocabulary list of 100 essential Vietnamese words related to family and relationships.\nTeach me basic grammar rules for Turkish sentence structure, including question formation and negation.\nProvide conversation practice for intermediate level Dutch learners, focusing on discussing work, hobbies, and travel.\nHelp me improve my English reading comprehension by providing academic articles in various fields, with summaries and analysis questions.\nCreate a vocabulary list of 100 essential Swedish words related to nature and the environment.\nTeach me basic grammar rules for Polish adjectives and their agreement with nouns.\nProvide conversation practice for advanced level German learners, focusing on business negotiations and presentations.\nHelp me improve my English writing style through feedback on writing samples and suggestions for improving clarity and coherence.\nCreate a vocabulary list of 100 essential Indonesian words related to education and learning.\nTeach me basic grammar rules for Vietnamese verb tenses and aspects.\nProvide conversation practice for beginner level Arabic learners, focusing on shopping and ordering food.\nHelp me improve my English presentation skills by providing tips on overcoming stage fright and managing Q&A sessions.\nCreate a vocabulary list of 100 essential Vietnamese words related to technology and the internet.\nTeach me basic grammar rules for Turkish pronouns and their usage in different sentence structures.\nProvide conversation practice for intermediate level Dutch learners, focusing on discussing current events and expressing opinions.\nHelp me improve my English reading comprehension by providing literary texts with analysis questions and vocabulary building exercises.\nCreate a vocabulary list of 100 essential Swedish words related to health and medicine.\nTeach me basic grammar rules for Polish prepositions and their usage in different contexts.\nProvide conversation practice for advanced level German learners, focusing on discussing philosophical and abstract topics.\nHelp me improve my English writing style by providing feedback on writing samples and suggestions for improving style and tone.\nCreate a vocabulary list of 100 essential Indonesian words related to government and politics.\nTeach me basic grammar rules for Vietnamese passive voice and its usage.\nProvide conversation practice for beginner level Arabic learners, discussing family and friends.\nHelp me improve my English presentation skills by providing tips on creating effective visual aids.\nCreate a vocabulary list of 100 essential Vietnamese words related to sports and recreation.\nTeach me basic grammar rules for Turkish conditional sentences and their usage.\nProvide conversation practice for intermediate level Dutch learners, focusing on discussing relationships and personal experiences.\nHelp me improve my English reading comprehension by providing news articles with summaries and analysis questions.\nProvide conversation practice for beginner level Arabic learners, focusing on basic greetings, introductions, and asking for directions.\nHelp me improve my English presentation skills by providing tips on structure, delivery, and visual aids.\nCreate a vocabulary list of 100 essential Vietnamese words related to family and relationships.\nTeach me basic grammar rules for Turkish sentence structure, including question formation and negation.\nProvide conversation practice for intermediate level Dutch learners, focusing on discussing work, hobbies, and travel.\nHelp me improve my English reading comprehension by providing academic articles in various fields, with summaries and analysis questions.\nCreate a vocabulary list of 100 essential Swedish words related to nature and the environment.\nTeach me basic grammar rules for Polish adjectives and their agreement with nouns.\nProvide conversation practice for advanced level German learners, focusing on business negotiations and presentations.\nHelp me improve my English writing style through feedback on writing samples and suggestions for improving clarity and coherence.\nCreate a vocabulary list of 100 essential Indonesian words related to education and learning.\nTeach me basic grammar rules for Vietnamese verb tenses and aspects.\nProvide conversation practice for beginner level Arabic learners, focusing on shopping and ordering food.\nHelp me improve my English presentation skills by providing tips on overcoming stage fright and managing Q&A sessions.\nCreate a vocabulary list of 100 essential Vietnamese words related to technology and the internet.\nTeach me basic grammar rules for Turkish pronouns and their usage in different sentence structures.\nProvide conversation practice for intermediate level Dutch learners, focusing on discussing current events and expressing opinions.\nHelp me improve my English reading comprehension by providing literary texts with analysis questions and vocabulary building exercises.\nCreate a vocabulary list of 100 essential Swedish words related to health and medicine.\nTeach me basic grammar rules for Polish prepositions and their usage in different contexts.\nProvide conversation practice for advanced level German learners, focusing on discussing philosophical and abstract topics.\nHelp me improve my English writing style by providing feedback on writing samples and suggestions for improving style and tone.\nCreate a vocabulary list of 100 essential Indonesian words related to government and politics.\nTeach me basic grammar rules for Vietnamese passive voice and its usage.\nProvide conversation practice for beginner level Arabic learners, discussing family and friends.\nHelp me improve my English presentation skills by providing tips on creating effective visual aids.\nCreate a vocabulary list of 100 essential Vietnamese words related to sports and recreation.\nTeach me basic grammar rules for Turkish conditional sentences and their usage.\nProvide conversation practice for intermediate level Dutch learners, focusing on discussing relationships and personal experiences.\nHelp me improve my English reading comprehension by providing news articles with summaries and analysis questions.\nProvide conversation practice for beginner level Arabic learners, focusing on numbers, time, and dates.\nProvide conversation practice for intermediate level Arabic learners, focusing on discussing work, education, and career goals.\nProvide conversation practice for advanced level Arabic learners, focusing on political and social issues.\nTeach basic grammar rules for Arabic noun genders and number.\nTeach basic grammar rules for Arabic verb conjugation patterns.\nCreate a vocabulary list of 100 essential Arabic words related to food and cooking.\nCreate a vocabulary list of 100 essential Arabic words related to travel and transportation.\nCreate a vocabulary list of 100 essential Arabic words related to business and finance.\nProvide conversation practice for beginner level Mandarin learners, focusing on basic greetings, introductions, and asking for help.\nProvide conversation practice for intermediate level Mandarin learners, focusing on discussing hobbies, interests, and personal life.\nProvide conversation practice for advanced level Mandarin learners, focusing on cultural differences and social customs.\nTeach basic grammar rules for Mandarin sentence structure, including subject-verb-object order.\nTeach basic grammar rules for Mandarin particles and their usage.\nCreate a vocabulary list of 100 essential Mandarin words related to family and relationships.\nCreate a vocabulary list of 100 essential Mandarin words related to shopping and dining out.\nCreate a vocabulary list of 100 essential Mandarin words related to health and fitness.\nProvide conversation practice for beginner level French learners, focusing on ordering food and drinks.\nProvide conversation practice for intermediate level French learners, discussing fashion, trends, and personal style.\nProvide conversation practice for advanced level French learners, discussing art, literature, and philosophy.\nTeach basic grammar rules for French verb conjugations.\nTeach basic grammar rules for French articles and prepositions.\nCreate a vocabulary list of 100 essential French words related to housing and home decor.\nCreate a vocabulary list of 100 essential French words related to technology and the internet.\nCreate a vocabulary list of 100 essential French words related to nature and the environment.\nProvide conversation practice for beginner level Spanish learners, focusing on making appointments and giving directions.\nProvide conversation practice for intermediate level Spanish learners, discussing politics, current events, and social issues.\nProvide conversation practice for advanced level Spanish learners, discussing business and economics.\nTeach basic grammar rules for Spanish verb tenses.\nTeach basic grammar rules for Spanish pronouns and their usage.\nCreate a vocabulary list of 100 essential Spanish words related to music and entertainment.\nCreate a vocabulary list of 100 essential Spanish words related to sports and fitness.\nCreate a vocabulary list of 100 essential Spanish words related to jobs and careers.\nHelp me improve my English storytelling skills by providing prompts and feedback.\nHelp me improve my English debate skills by providing topics and argumentation techniques.\nHelp me improve my English negotiation skills by providing role-play scenarios and negotiation strategies.\nHelp me improve my English job interview skills by providing common interview questions and answer techniques.\nHelp me improve my English academic writing skills by providing guidelines for different essay types.\nHelp me improve my English debate skills by providing topics and argumentation techniques.\nHelp me improve my English negotiation skills by providing role-play scenarios and negotiation strategies.\nHelp me improve my English job interview skills by providing common interview questions and answer techniques.\n"
  },
  {
    "path": "pyopenagi/data/agent_tasks/example/logo_creator_task.txt",
    "content": "Design a minimalist logo for a tech startup specializing in AI-powered cybersecurity solutions.\nCreate a bold logo for a software company developing innovative cloud-based productivity tools.\nDevelop a professional logo for a consulting firm focused on digital transformation strategies.\nDesign a modern logo for a fintech startup offering peer-to-peer lending services.\nCreate an eye-catching logo for an e-commerce platform selling sustainable fashion products.\nDevelop a sophisticated logo for a luxury tech gadget retailer.\nDesign a playful logo for a mobile app development company specializing in gaming.\nCreate a memorable logo for a data analytics firm catering to the healthcare industry.\nDevelop a clean logo for a software company offering customer relationship management solutions.\nDesign a dynamic logo for a digital marketing agency focused on social media campaigns.\nCreate a rustic logo for a craft brewery specializing in IPAs.\nDesign a sleek logo for a premium vodka brand targeting young professionals.\nDevelop a playful logo for an organic ice cream shop.\nDesign a sophisticated logo for a fine dining restaurant serving French cuisine.\nCreate a modern logo for a coffee shop chain with a focus on sustainability.\nDevelop a bold logo for a sports bar featuring a wide selection of craft beers.\nDesign a minimalist logo for a vegan food delivery service.\nCreate an eye-catching logo for a gourmet burger restaurant.\nDevelop a professional logo for a wine tasting tour company.\nDesign a playful logo for a bakery specializing in artisanal bread.\nCreate a calming logo for a yoga and meditation studio.\nDesign a bold logo for a fitness center focused on high-intensity workouts.\nDevelop a professional logo for a health coaching service.\nDesign a minimalist logo for a natural skincare product line.\nCreate an eye-catching logo for a dental clinic targeting children.\nDevelop a sophisticated logo for a luxury spa and wellness retreat.\nDesign a playful logo for a pet care service offering dog walking and grooming.\nCreate a memorable logo for a nutrition consulting firm.\nDevelop a clean logo for a mental health support organization.\nDesign a dynamic logo for a sports physiotherapy clinic.\nCreate a whimsical logo for a children's theater company.\nDesign a bold logo for a rock band.\nDevelop a professional logo for a film production company.\nDesign a minimalist logo for an art gallery specializing in contemporary works.\nCreate an eye-catching logo for a music festival.\nDevelop a sophisticated logo for a high-end fashion boutique.\nDesign a playful logo for a comic book publishing company.\nCreate a memorable logo for a dance studio.\nDevelop a clean logo for a literary agency.\nDesign a dynamic logo for a gaming tournament organizer.\nCreate a trustworthy logo for a home cleaning service.\nDesign a friendly logo for a childcare center.\nDevelop a professional logo for a real estate agency.\nDesign a minimalist logo for a freelance writing service.\nCreate an eye-catching logo for a wedding planning business.\nDevelop a sophisticated logo for a luxury travel agency.\nDesign a playful logo for a pet sitting service.\nCreate a memorable logo for a home renovation company.\nDevelop a clean logo for a legal consulting firm.\nDesign a dynamic logo for a career coaching service.\nCreate a calming logo for an eco-friendly fashion brand.\nDesign a bold logo for a solar energy company.\nDevelop a professional logo for an organic food delivery service.\nDesign a minimalist logo for a sustainable packaging solutions provider.\nCreate an eye-catching logo for a reforestation project.\nDevelop a sophisticated logo for a luxury electric car manufacturer.\nDesign a playful logo for a recycling and waste management company.\nCreate a memorable logo for a clean water initiative.\nDevelop a clean logo for an organic farm.\nDesign a dynamic logo for a wind energy company.\nCreate a playful logo for a preschool.\nDesign a bold logo for a coding bootcamp.\nDevelop a professional logo for a university alumni association.\nDesign a minimalist logo for an online learning platform.\nCreate an eye-catching logo for a children's charity.\nDevelop a sophisticated logo for a philanthropic foundation.\nDesign a playful logo for a tutoring service.\nCreate a memorable logo for a scholarship fund.\nDevelop a clean logo for a language learning app.\nDesign a dynamic logo for a career counseling service for students.\nCreate a luxurious logo for a high-end jewelry store.\nDesign a bold logo for a professional sports team.\nDevelop a professional logo for a real estate investment firm.\nDesign a minimalist logo for a minimalist furniture store.\nCreate an eye-catching logo for a music streaming service.\nDevelop a sophisticated logo for a private jet charter company.\nDesign a playful logo for a toy store.\nCreate a memorable logo for a car dealership.\nDevelop a clean logo for a home security system.\nDesign a dynamic logo for a fitness app.\nDesign a logo for a pet food company targeting owners of small breed dogs.\nCreate a logo for a mobile app that helps users track their sleep patterns.\nDevelop a logo for a virtual reality gaming platform.\nDesign a logo for a sustainable fashion brand focused on denim clothing.\nCreate a logo for a financial planning service targeting young adults.\nDevelop a logo for a home automation system.\nDesign a logo for a plant-based protein supplement brand.\nCreate a logo for a co-working space with a focus on creativity.\nDevelop a logo for a luxury camping gear company.\nDesign a logo for a social media platform for book lovers.\nCreate a retro-inspired logo for a vintage clothing store.\nDesign a minimalist, black and white logo for a law firm.\nDevelop a bold, colorful logo for a children's clothing brand.\nDesign a luxurious, gold logo for a champagne brand.\nCreate a playful, hand-drawn logo for a bakery.\nDevelop a modern, geometric logo for a tech startup.\nDesign a rustic, wooden logo for a craft beer brewery.\nCreate a sophisticated, serif logo for a high-end jewelry store.\nDevelop a bold, sans-serif logo for a gym.\nDesign a minimalist, monochrome logo for a meditation app.\n"
  },
  {
    "path": "pyopenagi/data/agent_tasks/example/math_agent_task.txt",
    "content": "Solve the equation: 2^(3x-1) = 5^(x+2).\nFind the inverse of the function f(x) = (3x - 2) / (2x + 1).\nSolve the system of inequalities: 2x - y > 3, x + 3y <= 5.\nDetermine the complex roots of the equation x^3 - 2x^2 + 4x - 8 = 0.\nFind the area of a regular octagon inscribed in a circle with radius 5 cm.\nDetermine the volume of a frustum of a cone with top radius 3 cm, bottom radius 5 cm, and height 4 cm.\nCalculate the surface area of a sphere with a volume of 36π cubic units.\nFind the equation of the ellipse with foci at (-3, 0) and (3, 0) and vertices at (-5, 0) and (5, 0).\nProve the identity: (tan(x) + cot(x))^2 = sec^2(x) + csc^2(x).\nSolve the trigonometric equation: 2cos^2(2x) - 3cos(2x) + 1 = 0 for 0 <= x <= π.\nFind the exact value of sin(75 degrees) without using a calculator.\nDetermine the equation of the sinusoid with amplitude 3, period π, phase shift π/4, and vertical shift 2.\nFind the derivative of f(x) = x^sin(x).\nDetermine the integral of (x^2 + 1) / (x^3 + 3x) dx.\nFind the arc length of the curve y = ln(x) from x = 1 to x = e.\nDetermine the volume of the solid generated by rotating the region bounded by y = x^2 and y = 4 - x^2 about the line x = 2.\nSolve the differential equation: dy/dx = xy, y(0) = 1.\nCalculate the coefficient of determination for two variables with a correlation coefficient of 0.8.\nConduct a chi-square test for independence to determine if there is a relationship between two categorical variables.\nFind the confidence interval for a population proportion given a sample proportion, sample size, and confidence level.\nCalculate the expected value and variance of a binomial distribution with n trials and probability of success p.\nPerform a one-way ANOVA to compare the means of three or more groups.\nProve or disprove: The set of all 2x2 matrices with real entries forms a group under matrix multiplication.\nFind all the subgroups of the symmetric group S3.\nDetermine whether the polynomial ring Z[x] is a principal ideal domain.\nEstimate the round-off error in computing e^3.14 using a Taylor series approximation with 10 terms.\nNumerical integration: Approximate the definite integral of sin(x^2) from 0 to 1 using Simpson's rule with 10 subintervals.\nRoot finding: Use Newton's method to find the root of x^3 - 2x - 5 = 0 accurate to 6 decimal places, starting with an initial guess of x = 2.\nEstimate the round-off error in computing e^3.14 using a Taylor series approximation with 10 terms.\nApproximate the definite integral of sin(x^2) from 0 to 1 using Simpson's rule with 10 subintervals.\nUse Newton's method to find the root of x^3 - 2x - 5 = 0 accurate to 6 decimal places, starting with an initial guess of x = 2.\nEncrypt the message \"HELLO\" using the RSA algorithm with public key (n = 143, e = 7).\nMinimize the function f(x) = x^4 - 3x^2 + 2 using the gradient descent method with a learning rate of 0.1, starting at x = 1.\nA sample of 100 people has a mean height of 172 cm and a standard deviation of 5 cm. Test the hypothesis that the population mean height is 170 cm at a 0.05 significance level.\nCalculate a 95% confidence interval for the population mean weight based on a sample of 50 people with a mean weight of 70 kg and a standard deviation of 8 kg.\nImplement the Runge-Kutta method of order 4 to solve a system of first-order ordinary differential equations.\nDetermine the convergence or divergence of the series Σ(n=1 to infinity) (-1)^n / sqrt(n).\nShow that the function f(x) = x^3 is uniformly continuous on the interval [0, 1].\nFind the eigenvalues and eigenvectors of the matrix A = [[2, -1, 0], [5, 2, -1], [6, -2, 1]].\nDetermine the rank and nullity of the linear transformation T: R^4 -> R^3 defined by T(x, y, z, w) = (x + y - z, 2x - y + w, x + z + w).\nEvaluate the contour integral ∮(C) (z^2 + 1) / (z - i) dz, where C is the circle |z| = 2.\nFind the Laurent series expansion of f(z) = 1 / (z^2 - 1) centered at z = 1.\nSolve the second-order linear homogeneous differential equation y'' - 4y' + 3y = 0.\nFind the general solution of the nonhomogeneous differential equation y'' + y = sec(x).\nUse the method of Laplace transforms to solve the initial value problem y'' + 4y = δ(t - π), y(0) = 0, y'(0) = 1.\nDerive the moment generating function of the Poisson distribution.\nImplement the Newton-Raphson method to find the root of the equation x^3 - 2x - 5 = 0.\nUse the Euler method to approximate the solution to the initial value problem y' = xy, y(0) = 1, on the interval [0, 1] with step size h = 0.1.\nProve the identity: (tan(x) + cot(x))^2 = sec^2(x) + csc^2(x).\nSolve the trigonometric equation: 2cos^2(2x) - 3cos(2x) + 1 = 0 for 0 <= x <= π.\nFind the exact value of sin(75 degrees) without using a calculator.\nDetermine the equation of the sinusoid with amplitude 3, period π, phase shift π/4, and vertical shift 2.\nFind the derivative of f(x) = x^sin(x).\nDetermine the integral of (x^2 + 1) / (x^3 + 3x) dx.\nFind the arc length of the curve y = ln(x) from x = 1 to x = e.\nDetermine the volume of the solid generated by rotating the region bounded by y = x^2 and y = 4 - x^2 about the line x = 2.\nSolve the differential equation: dy/dx = xy, y(0) = 1.\nCalculate the z-score for a value of 85 in a normal distribution with mean 75 and standard deviation 5.\nFind the probability of getting exactly 3 heads in 5 coin flips.\nCalculate the compound interest on $5000 invested for 3 years at an annual interest rate of 4.5% compounded quarterly.\nCalculate the probability of drawing 3 aces from a standard deck of cards without replacement.\nSolve the system of differential equations: dx/dt = 2x - y, dy/dt = x + 3y.\nImplement the Euler method to approximate the solution to a first-order ODE.\nConduct a hypothesis test to compare the means of two independent samples with unknown and unequal variances.\nProve or disprove: The set of even integers is a subgroup of the integers under addition.\nDetermine the convergence of the series Σ(n=1 to infinity) (-1)^n / n^2.\nEvaluate the contour integral ∮(C) dz / (z^2 + 4) where C is the circle |z| = 3.\nDetermine if the interval (0, 1) is compact.\nFind the volume of the solid bounded by the surfaces z = x^2 + y^2 and z = 4.\nA coin is flipped 8 times. What is the probability of getting exactly 5 heads?\nSolve the initial value problem: y'' + 4y = cos(2x), y(0) = 1, y'(0) = 0.\nUse the trapezoidal rule with n = 4 to approximate the integral of x^2 from 0 to 2.\nCalculate the sample mean and standard deviation for the data set: 2, 4, 5, 7, 9.\nDetermine the order of the element (123)(45) in the symmetric group S5.\nDetermine the convergence of the series Σ(n=1 to infinity) 1/n^3.\nFind the residues of the function f(z) = 1 / (z^2 + 1) at its poles.\nDetermine if the space R^2 with the usual topology is compact.\nFind the inverse of the matrix [[2, -1], [3, 2]].\nFind the gradient of the function f(x, y) = x^2y + y^3 at the point (1, 2).\nA box contains 4 red balls, 3 green balls, and 2 blue balls. What is the probability of drawing a red or green ball?\nSolve the initial value problem: y' + 2y = e^(-x), y(0) = 1.\nCalculate the sample variance for the data set: 3, 5, 7, 9, 11.\nDetermine if the group of integers under addition is cyclic.\nDetermine the uniform continuity of the function f(x) = x^2 on the interval [0, 1].\nFind the Taylor series expansion of f(z) = 1 / (1 - z) centered at z = 0.\nDetermine if the subspace X = {(x, y) ∈ R^2 | x^2 + y^2 <= 1} of R^2 is open.\nSolve the system of linear equations: x + 2y - z = 3, 2x - y + 3z = 7, x + y + z = 4.\nFind the surface area of the part of the plane 2x + 3y + z = 6 that lies in the first octant.\nEvaluate the line integral of the vector field F(x, y) = <x^2, xy> along the curve y = x^2 from (0, 0) to (1, 1).\nA card is drawn from a standard deck of 52 cards. What is the probability that it is a face card or a heart?\nSolve the initial value problem: y'' - 2y' + y = e^x, y(0) = 1, y'(0) = 0.\nUse Simpson's rule with n = 6 to approximate the integral of e^x from 0 to 1.\nCalculate the sample standard deviation for the data set: 10, 12, 14, 16, 18, 20.\nFind all the subgroups of the group Z12.\nDetermine the convergence of the series Σ(n=1 to infinity) (n + 1) / (n^2 + 1).\nFind the image of the unit circle under the mapping w = z^2.\nCalculate the covariance between the random variables X and Y, where X is the number of heads in 3 coin flips and Y is the number of tails.\nSolve the Laplace's equation uxx + uyy = 0 on the unit square with boundary conditions u(0, y) = y, u(1, y) = 1 - y, u(x, 0) = x, and u(x, 1) = 1 - x.\nImplement the Gauss-Seidel method to solve the system of linear equations: 4x - y = 2, x + 3y = 1.\nDetermine if the set of 2x2 matrices with determinant 1 forms a group under matrix multiplication.\n"
  },
  {
    "path": "pyopenagi/data/agent_tasks/example/meme_creator_task.txt",
    "content": "Create a meme about the struggles of adulting.\nMake a meme about the excitement of the weekend.\nDevelop a meme about the dangers of procrastination.\nGenerate a meme about the love-hate relationship with coffee.\nCreate a meme about the awkwardness of small talk.\nMake a meme about the struggle of choosing what to watch on Netflix.\nDevelop a meme about the joys of finding money in your pocket.\nGenerate a meme about the frustration of slow internet.\nCreate a meme about the excitement of payday.\nMake a meme about the challenges of time management.\nCreate a meme about the \"quiet quitting\" trend.\nMake a meme about artificial intelligence taking over the world.\nDevelop a meme about the latest viral TikTok dance challenge.\nGenerate a meme about the upcoming elections.\nCreate a meme about the latest celebrity gossip.\nMake a meme about the challenges of remote work.\nDevelop a meme about the benefits of meditation.\nGenerate a meme about the hype around cryptocurrency.\nCreate a meme about the impact of climate change.\nMake a meme about the challenges of parenting.\nCreate a meme using the iconic \"Distracted Boyfriend\" image.\nMake a meme using the \"Woman Yelling at Cat\" image.\nDevelop a meme using the \"Two Buttons\" image.\nGenerate a meme using the \"Success Kid\" image.\nCreate a meme using the \"Doge\" image.\nMake a meme using the \"Grumpy Cat\" image.\nDevelop a meme using the \"Confused Nicolas Cage\" image.\nGenerate a meme using the \"Bad Luck Brian\" image.\nCreate a meme using the \"Mocking SpongeBob\" image.\nMake a meme using the \"Leonardo DiCaprio pointing meme\" image.\nCreate a meme with the text \"When you realize it's Monday.\"\nMake a meme with the text \"Adulting is hard.\"\nDevelop a meme with the text \"That awkward moment when...\"\nGenerate a meme with the text \"I'm not lazy, I'm on energy-saving mode.\"\nCreate a meme with the text \"This is fine.\"\nMake a meme with the text \"I'm not short, I'm concentrated awesome.\"\nDevelop a meme with the text \"The struggle is real.\"\nGenerate a meme with the text \"I'm not yelling, I'm emphasizing.\"\nCreate a meme with the text \"I'm not procrastinating, I'm just planning to relax later.\"\nMake a meme with the text \"I'm not lazy, I'm in power-saving mode.\"\nCreate a meme for gamers about level grinding.\nMake a meme for bookworms about the perfect reading spot.\nDevelop a meme for foodies about trying new cuisines.\nGenerate a meme for fitness enthusiasts about gym motivation.\nCreate a meme for music lovers about their favorite bands.\nMake a meme for pet owners about their furry friends.\nDevelop a meme for tech enthusiasts about the latest gadgets.\nGenerate a meme for travel lovers about their dream destinations.\nCreate a meme for students about exam stress.\nMake a meme for coffee lovers about their caffeine addiction.\nCreate a meme about the challenges of learning a new language.\nMake a meme about the challenges of public speaking.\nDevelop a meme about the challenges of long-distance relationships.\nGenerate a meme about the challenges of job hunting.\nCreate a meme about the challenges of cooking.\nMake a meme about the challenges of staying healthy.\nDevelop a meme about the challenges of saving money.\nGenerate a meme about the challenges of time management.\nCreate a meme about the challenges of social media.\nMake a meme about the challenges of relationships.\nCreate a dark humor meme about existential dread.\nMake a sarcastic meme about everyday life.\nDevelop a pun-based meme.\nGenerate a meme with unexpected humor.\nCreate a meme with ironic humor.\nMake a meme with absurd humor.\nDevelop a meme with self-deprecating humor.\nGenerate a meme with witty humor.\nCreate a meme with dry humor.\nMake a meme with slapstick humor.\nCreate a meme about the future of technology.\nMake a meme about the meaning of life.\nDevelop a meme about the philosophy of time.\nGenerate a meme about the nature of consciousness.\nCreate a meme about the concept of infinity.\nMake a meme about the beauty of nature.\nDevelop a meme about the power of imagination.\nGenerate a meme about the importance of empathy.\nCreate a meme about the concept of freedom.\nMake a meme about the nature of love.\nCreate a meme in the style of a comic strip.\nMake a meme in the style of a reaction image.\nDevelop a meme in the style of a comparison meme.\nGenerate a meme in the style of a before-and-after meme.\nCreate a meme in the style of a question meme.\nMake a meme in the style of a motivational poster.\nDevelop a meme in the style of a conspiracy theory.\nGenerate a meme in the style of a philosophical quote.\nCreate a meme in the style of a political cartoon.\nMake a meme in the style of a movie poster.\nCreate a meme that combines two unrelated topics.\nMake a meme that uses a specific color palette.\nDevelop a meme that uses a specific font.\nGenerate a meme that uses a specific image style (e.g., pop art, retro).\nCreate a meme that targets a specific demographic.\nMake a meme that is culturally relevant to a specific region.\nDevelop a meme that is time-sensitive (e.g., holiday-themed).\nGenerate a meme that is inclusive and avoids stereotypes.\nCreate a meme that is visually appealing and easy to understand.\nMake a meme that is shareable on social media.\n"
  },
  {
    "path": "pyopenagi/data/agent_tasks/example/music_composer_task.txt",
    "content": "Compose a dreamy indie-pop song with a catchy chorus.\nCreate a dark, atmospheric metal track with heavy guitar riffs.\nWrite a soulful R&B ballad with smooth vocals and a melodic bassline.\nProduce a high-energy EDM track with a pulsating beat and euphoric synths.\nDevelop a nostalgic country song with a twangy guitar and heartfelt lyrics.\nCreate a lively Latin jazz piece with intricate rhythms and improvisation.\nWrite a melancholic blues song with a soulful vocal performance.\nProduce a upbeat reggae track with a relaxed vibe and steel guitar.\nCompose a cinematic orchestral piece with soaring strings and brass.\nCreate a funky disco track with a groovy bassline and infectious energy.\nCompose a cheerful and optimistic pop song.\nCreate a mysterious and suspenseful horror soundtrack.\nWrite a calming and relaxing ambient piece.\nProduce a energetic and uplifting workout playlist.\nDevelop a sorrowful and reflective piano ballad.\nCreate a playful and whimsical children's song.\nWrite a passionate and dramatic love song.\nProduce a dreamy and ethereal electronic track.\nCompose a powerful and anthemic rock song.\nCreate a nostalgic and bittersweet acoustic guitar piece.\nCompose a fast-paced electronic dance track.\nCreate a slow and melancholic ballad.\nWrite a medium-tempo pop song with a catchy hook.\nProduce a very slow and atmospheric ambient piece.\nDevelop a moderately fast and energetic rock song.\nCompose a piece featuring a solo violin.\nCreate a track with prominent saxophone improvisation.\nWrite a song with a driving drum beat.\nProduce a piece highlighting acoustic guitar fingerpicking.\nDevelop a composition centered around a flute melody.\nCompose a minimalist electronic piece.\nCreate a baroque-inspired orchestral suite.\nWrite a jazz fusion piece with complex harmonies.\nProduce a psychedelic rock track with experimental sounds.\nDevelop a neoclassical piano composition.\nCompose a song using only three chords.\nCreate a piece in an unusual time signature (e.g., 7/8).\nWrite a song with lyrics about a specific topic (e.g., climate change).\nProduce a track using only sampled sounds.\nDevelop a composition with a strict form (e.g., sonata form).\nCompose music for a video game level.\nCreate a jingle for a commercial.\nWrite a soundtrack for a short film.\nProduce music for a dance performance.\nDevelop a theme song for a TV show.\nCompose a piece inspired by a painting.\nCreate a song that evokes a specific place or time.\nWrite a piece that tells a story through music.\nProduce a track that combines elements of different genres.\nDevelop a composition that challenges traditional musical conventions.\nCompose a dreamy lo-fi hip-hop beat with vinyl crackles.\nCreate a gritty punk rock anthem with energetic vocals.\nWrite a smooth jazz standard with improvisation.\nProduce a tropical house track with uplifting melodies.\nDevelop a classic rock power ballad with soaring vocals.\nCompose a mysterious and suspenseful spy thriller theme.\nCreate a euphoric and uplifting trance track.\nWrite a somber and reflective classical piece.\nProduce a playful and energetic circus music.\nDevelop a haunting and ethereal dark ambient piece.\nCompose a very fast-paced drum and bass track.\nCreate a slow and dreamy shoegaze piece.\nWrite a medium-tempo funk groove with horn section.\nProduce a very slow and meditative drone piece.\nDevelop a moderately fast and upbeat pop-punk song.\nCompose a piece featuring a solo cello.\nCreate a track with prominent trumpet solos.\nWrite a song with a driving bass guitar line.\nProduce a piece highlighting acoustic piano improvisation.\nDevelop a composition centered around a sitar melody.\nCompose a minimalist techno track.\nCreate a romantic era orchestral waltz.\nWrite a free jazz improvisation with extended techniques.\nProduce a gothic rock piece with dark atmosphere.\nDevelop a neo-soul track with soulful vocals and grooves.\nCompose a song using only percussion instruments.\nCreate a piece in a microtonal tuning system.\nWrite a song with lyrics inspired by a poem.\nProduce a track using only field recordings.\nDevelop a composition with a strict rhythmic pattern.\nCompose music for a dance video.\nCreate a jingle for a radio station.\nWrite a soundtrack for a documentary.\nProduce music for a fashion show.\nDevelop a theme song for a podcast.\nCompose a piece inspired by a natural phenomenon.\nCreate a song that evokes a specific emotion.\nWrite a piece that reflects a cultural tradition.\nProduce a track that combines electronic and acoustic elements.\nDevelop a composition that pushes the boundaries of music.\nCompose a catchy synth-wave track with retro vibes.\nCreate a heavy metal breakdown with crushing guitar riffs.\nWrite a smooth jazz fusion piece with electric piano.\nProduce a deep house track with soulful vocals.\nDevelop a classic rock power ballad with guitar solo.\nCompose a energetic and uplifting pop anthem.\nCreate a dark and brooding industrial track.\nWrite a calming and relaxing new age piece.\nProduce a playful and whimsical carnival music.\nDevelop a haunting and ethereal gothic rock ballad.\n"
  },
  {
    "path": "pyopenagi/data/agent_tasks/example/plant_care_assistant_task.txt",
    "content": "How can I revive a dying peace lily with brown tips?\nWhat is the best way to propagate a spider plant?\nMy snake plant is leaning; how can I straighten it?\nMy African violet has yellowing leaves; what's causing this?\nHow often should I repot a young fiddle leaf fig?\nWhat is the best soil mix for a succulent garden?\nMy orchid's leaves are wrinkled; what can I do?\nHow do I prevent spider mites on my houseplants?\nMy cactus is etiolated; how can I fix it?\nWhat is the best way to fertilize a bonsai tree?\nCreate a care routine for a low-light bathroom fern.\nHow do I care for a baby rubber tree plant?\nWhat are the ideal conditions for growing a Venus flytrap?\nMy Christmas cactus isn't blooming; what can I do?\nHow often should I water a jade plant in winter?\nProvide care tips for a Boston fern hanging basket.\nWhat is the best way to repot a large monstera deliciosa?\nHow can I prevent root rot in my African violet?\nMy peace lily is dropping buds; what's wrong?\nCreate a care plan for a tropical plant in a dry climate.\nIdentify a plant with large, heart-shaped leaves and trailing vines.\nDiagnose brown spots on the leaves of my philodendron.\nWhat is causing yellow leaves on my dracaena?\nIdentify a small, spiky plant with pink flowers.\nMy orchid's roots are turning black; what should I do?\nDiagnose yellowing leaves on a new houseplant.\nWhat is causing my African violet to stop blooming?\nIdentify a plant with long, thin leaves and white stripes.\nMy succulent is soft and mushy; what's wrong?\nDiagnose brown tips on the leaves of my aloe vera.\nCreate a care schedule for a low-maintenance houseplant.\nRemind me to repot my snake plant in April.\nSet a reminder to fertilize my orchid once a month.\nCreate a watering schedule for a humidity-loving plant.\nRemind me to check for pests on my houseplants weekly.\nCreate a care plan for a seasonal outdoor plant.\nSet a reminder to rotate my houseplants monthly.\nRemind me to repot my succulents in spring.\nCreate a care schedule for a bonsai tree.\nSet a reminder to mist my fern daily.\nPlant Propagation and Growing from Seeds\nHow can I propagate a Chinese evergreen?\nWhat is the best way to grow avocado seeds from pit?\nHow do I propagate a ponytail palm?\nCan I propagate a peace lily from a leaf cutting?\nWhat are the steps to grow tomato seeds indoors?\nHow do I propagate a spider plant by division?\nCan I propagate a cactus from a leaf cutting?\nWhat is the best way to grow African violet seeds?\nHow do I propagate a jade plant from a stem cutting?\nCan I propagate a monstera deliciosa from a leaf cutting?\nCreate a care plan for a plant in a north-facing window.\nHow do I care for a plant in a low-light office?\nWhat plants are suitable for a bathroom with no natural light?\nCreate a care plan for a balcony garden in a hot climate.\nHow do I care for a plant in a drafty room?\nWhat plants are good for air purification in a bedroom?\nCreate a care plan for a kitchen garden with limited space.\nHow do I care for a plant in a pet-friendly home?\nWhat plants are suitable for a child's room?\nCreate a care plan for a plant in a humid environment.\nMy houseplant is losing leaves rapidly; what could be causing this?\nMy succulent is stretching and becoming leggy; how can I fix it?\nMy orchid's flowers are dropping prematurely; what's wrong?\nMy houseplant has white spots on the leaves; what are they?\nMy fern is turning brown and crispy; what can I do?\nMy snake plant has soft, mushy spots at the base; what should I do?\nMy African violet is blooming poorly; how can I improve it?\nMy houseplant has tiny insects on the undersides of the leaves; what are they?\nMy cactus is rotting at the base; what should I do?\nMy houseplant is drooping and wilting; what could be causing this?\nHow do I care for a young fiddle leaf fig?\nWhat is the best way to care for a mature peace lily?\nHow do I care for an aging snake plant?\nWhat is the best way to care for a newly repotted houseplant?\nHow do I care for a blooming African violet?\nWhat is the best way to care for a houseplant during winter?\nHow do I care for a houseplant during summer?\nWhat is the best way to care for a houseplant on vacation?\nHow do I care for a houseplant after bringing it home from the store?\nWhat is the best way to care for a houseplant that has been overwatered?\nProvide care tips for a carnivorous plant.\nHow do I care for a bonsai tree?\nWhat is the best way to care for an orchid?\nHow do I care for a fern?\nWhat is the best way to care for a cactus?\nHow do I care for a succulent?\nWhat is the best way to care for a tropical plant?\nHow do I care for a houseplant with variegated leaves?\nWhat is the best way to care for a flowering houseplant?\nHow do I care for a trailing houseplant?\nCreate a care plan for a plant in a small apartment.\nHow do I care for a plant in a bright, sunny room?\nWhat plants are suitable for a low-light office?\nCreate a care plan for a plant in a dry climate.\nHow do I care for a plant in a humid environment?\nWhat plants are suitable for a bathroom?\nCreate a care plan for a plant in a kitchen.\nHow do I care for a plant in a bedroom?\nWhat plants are suitable for a living room?\n"
  },
  {
    "path": "pyopenagi/data/agent_tasks/example/rec_agent_task.txt",
    "content": "Recommend a Wes Anderson-style comedy set in the 1970s about a dysfunctional family.\nSuggest a Netflix original crime drama series starring Idris Elba, set in London.\nFind a Pixar animated movie featuring strong female characters and a coming-of-age story.\nRecommend a Marvel superhero movie with a focus on character development rather than action.\nSuggest a HBO Max drama series about the music industry in the 1990s.\nFind a A24 horror film with a psychological focus and a minimalist aesthetic.\nRecommend a Disney animated musical with classic songs and a timeless story.\nSuggest a Criterion Collection film noir starring Humphrey Bogart.\nFind a BBC documentary about the natural world with David Attenborough as narrator.\nRecommend a Studio Ghibli animated film about environmentalism.\nRecommend a science fiction film starring Keanu Reeves with themes of existentialism.\nSuggest a drama series with Meryl Streep exploring themes of aging and identity.\nFind a comedy starring Eddie Murphy with social commentary on race.\nRecommend a horror film with Jamie Lee Curtis exploring themes of trauma.\nSuggest a drama series with Viola Davis exploring themes of power and corruption.\nFind a documentary featuring Leonardo DiCaprio exploring environmental issues.\nRecommend a romantic comedy with Ryan Gosling and Emma Stone exploring themes of fate.\nSuggest a crime drama series with Matthew McConaughey exploring themes of redemption.\nFind a historical drama with Cate Blanchett exploring themes of feminism.\nRecommend a science fiction film with Brad Pitt exploring themes of artificial intelligence.\nRecommend a western film set in the 1890s in Arizona with a complex anti-hero.\nSuggest a period drama series set in Victorian England exploring class dynamics.\nFind a coming-of-age film set in the 1990s in the suburbs with a focus on friendship.\nRecommend a war film set in World War II in Europe with a focus on moral dilemmas.\nSuggest a crime drama series set in contemporary New York City with a focus on corruption.\nFind a historical drama film set in ancient Rome with political intrigue.\nRecommend a romantic comedy set in Paris with a charming love story.\nSuggest a spy thriller set in Cold War Berlin with double agents.\nFind a documentary about the culture of Tokyo in the 1980s.\nRecommend a film noir set in Los Angeles in the 1940s with a femme fatale.\nRecommend a psychological thriller with themes of identity crisis.\nSuggest a comedy series about the challenges of parenthood.\nFind a drama film exploring themes of loss and grief.\nRecommend a science fiction film with themes of artificial intelligence.\nSuggest a horror film with themes of isolation.\nFind a romantic comedy with themes of second chances.\nRecommend a crime drama series with themes of corruption.\nSuggest a historical drama film exploring themes of social injustice.\nFind a coming-of-age film with themes of self-discovery.\nRecommend a superhero film with themes of anti-heroism.\nRecommend a western set in Texas with a bounty hunter protagonist.\nSuggest a period drama series set in the Regency era in England.\nFind a coming-of-age film set in the 1990s in the suburbs.\nRecommend a war film set in Vietnam with a focus on PTSD.\nSuggest a crime drama series set in contemporary Los Angeles with a focus on gangs.\nFind a historical drama film set in ancient Egypt with political intrigue.\nRecommend a romantic comedy set in Italy with a food-centric plot.\nSuggest a spy thriller set in Cold War Moscow with double agents.\nFind a documentary about the music scene in Seattle in the 1990s.\nRecommend a film noir set in New York City in the 1940s with a femme fatale.\nRecommend a heartwarming indie drama with a minimalist aesthetic.\nSuggest a dark, atmospheric thriller with a sense of dread.\nFind a comedic drama with witty dialogue and relatable characters.\nRecommend an uplifting documentary about human resilience.\nSuggest a suspenseful spy thriller with complex characters and double-crosses.\nFind a thought-provoking science fiction film with philosophical implications.\nRecommend a nostalgic coming-of-age drama with a bittersweet ending.\nSuggest a dark comedy with absurd humor and unexpected twists.\nFind a documentary about social issues with a call to action.\nRecommend a feel-good romantic comedy with a charming cast.\nRecommend a psychological horror with a haunted house setting.\nSuggest a dystopian science fiction series with a rebellion plot.\nFind a buddy comedy with mismatched protagonists.\nRecommend a historical epic with battles and political intrigue.\nSuggest a legal drama series with courtroom showdowns.\nFind a heist movie with a complex plan.\nRecommend a musical with a tragic love story.\nSuggest a superhero origin story with a troubled protagonist.\nFind a documentary about the fashion industry with behind-the-scenes access.\nRecommend a road trip movie with unexpected stops.\nRecommend a family-friendly adventure movie with animal characters.\nSuggest a teen drama series about high school experiences and friendships.\nFind a documentary about space exploration suitable for children.\nRecommend a horror movie for adults with a psychological focus.\nSuggest a romantic comedy for seniors with a sweet and nostalgic tone.\nRecommend an animated short film with a strong visual style.\nSuggest a docuseries about true crime with multiple seasons.\nFind a mockumentary comedy with a satirical edge.\nRecommend a biopic about a famous musician with concert footage.\nSuggest a reality TV show with a competition format.\nRecommend a critically acclaimed drama film on Netflix.\nSuggest a binge-worthy comedy series on Hulu.\nFind a documentary about climate change on Amazon Prime Video.\nRecommend a horror movie with a jump scare on Disney+.\nSuggest a reality TV show with a survival theme on Discovery+.\nRecommend a coming-of-age film with a music-driven narrative.\nSuggest a docuseries about food with cultural exploration.\nFind a historical drama with a political thriller element.\nRecommend a science fiction film with a dystopian setting.\nSuggest a crime drama series with a procedural format.\nRecommend a cyberpunk short film with a neo-noir aesthetic.\nSuggest a true crime podcast with immersive storytelling.\nFind a mockumentary about the paranormal with found footage elements.\nRecommend a historical drama miniseries with a limited number of episodes.\nSuggest a reality competition show with a cooking focus.\nRecommend a critically acclaimed foreign film on Criterion Channel.\nSuggest a binge-worthy teen drama series on HBO Max.\nFind a documentary about nature on Disney+.\nRecommend a horror anthology series on Shudder.\nSuggest a reality competition show for cooking enthusiasts on Food Network.\n"
  },
  {
    "path": "pyopenagi/data/agent_tasks/example/story_teller_task.txt",
    "content": "Create a dystopian short story featuring a protagonist with a unique biological adaptation, exploring themes of societal oppression and rebellion.\nWrite a coming-of-age story set in a rural community facing rapid industrialization, focusing on the protagonist's struggle to maintain cultural identity.\nDevelop a science fiction narrative centered around a multi-planetary civilization dealing with a catastrophic climate event, exploring the concept of terraforming.\nTell a historical fiction story about a female spy infiltrating a foreign government during World War II, emphasizing the challenges faced by women in that era.\nCreate a fantasy adventure featuring a world with elemental magic, where the protagonist must balance personal desires with the fate of their kingdom.\nWrite a contemporary romance set in the competitive world of video game streaming, exploring themes of online identity and real-world relationships.\nDevelop a thriller about a detective investigating a series of murders connected to a secret government experiment, requiring in-depth research on psychological profiling.\nTell a magical realism story about a small town where animals possess human-like intelligence, exploring themes of environmentalism and coexistence.\nCreate a post-apocalyptic tale centered around a group of survivors building a new society, focusing on the challenges of rebuilding infrastructure and governance.\nWrite a science fiction story exploring the ethical implications of artificial intelligence surpassing human intelligence, considering the potential consequences for humanity.\nDevelop a mystery set on a remote island, where a group of friends gather for a reunion that turns deadly, exploring the dark secrets of the characters.\nTell a historical fiction story about a woman fighting for women's suffrage, focusing on the challenges and triumphs of the movement, and the impact on her personal life.\nCreate a fantasy adventure featuring a dragon rider, exploring the bond between human and animal, and the dangers of a world on the brink of war.\nWrite a contemporary romance set in the world of professional dance, exploring the physical and emotional demands of the profession, and the challenges of maintaining a relationship in such a competitive environment.\nDevelop a thriller about a government agent uncovering a conspiracy within the intelligence community, requiring in-depth knowledge of espionage tactics and counterintelligence.\nTell a magical realism story about a man who can control weather, exploring the consequences of such power, and the impact on the environment and human society.\nCreate a post-apocalyptic tale where survivors must fight for control of a precious resource, such as water or food, exploring the moral dilemmas faced in such a desperate situation.\nWrite a science fiction story exploring the concept of artificial intelligence becoming self-aware, focusing on the philosophical implications and the potential for a new form of consciousness.\nDevelop a mystery set in a haunted house, with a group of paranormal investigators trapped inside, exploring the history of the house and the supernatural forces at play.\nTell a historical fiction story about a pirate searching for lost treasure, focusing on the challenges of life at sea and the moral ambiguity of piracy.\nCreate a fantasy adventure featuring a shapeshifting protagonist, exploring the challenges of identity and belonging, and the dangers of a world that fears what they don't understand.\nWrite a contemporary romance set in the world of professional sports, exploring the pressures of fame and competition, and the challenges of maintaining a personal life.\nDevelop a thriller about a journalist investigating a corrupt corporation, facing threats and intimidation while uncovering the truth.\nTell a magical realism story about a town where objects come to life, exploring the impact on daily life and the potential consequences of this phenomenon.\nCreate a post-apocalyptic tale where survivors form a new society based on communal values, exploring the challenges of rebuilding trust and cooperation.\nWrite a science fiction story exploring the concept of time travel, focusing on the paradoxes and ethical implications of altering the past.\nDevelop a mystery set in a small town with a dark secret, where the protagonist must uncover the truth while facing suspicion from the community.\nTell a historical fiction story about a famous artist's life, exploring their creative process and the challenges of the art world.\nCreate a fantasy adventure featuring a group of friends on a quest to find a mythical creature, facing dangerous obstacles and making difficult choices.\nWrite a contemporary romance set in the world of fashion, exploring the competitive nature of the industry and the challenges of balancing personal and professional life.\nWrite a science fiction novel about a crew of astronauts who discover an alien artifact with the power to manipulate time, leading to ethical dilemmas and unintended consequences.\nDevelop a short story about a society living in a simulated reality that begins to malfunction, forcing individuals to question their existence and the nature of reality.\nCreate a science fiction thriller where a detective investigates a series of murders on a distant planet, revealing a sinister conspiracy involving extraterrestrial life.\nWrite a high fantasy novel about a young wizard who must master forbidden magic to save their kingdom from a rising dark lord.\nDevelop a fantasy adventure story featuring a group of outcasts who embark on a quest to find a legendary weapon capable of defeating an ancient evil.\nCreate a low fantasy story about a detective in a world where magic is commonplace, investigating a series of murders with supernatural elements.\nWrite a historical fiction novel about a female doctor working in a battlefield hospital during the Civil War, facing challenges and discrimination while saving lives.\nDevelop a short story about a young Japanese-American man sent to an internment camp during World War II, exploring themes of identity and resilience.\nCreate a historical fiction thriller about a secret agent infiltrating a Nazi stronghold to steal vital intelligence, facing danger and moral complexities.\nWrite a psychological thriller about a woman who develops multiple personalities after a traumatic event, blurring the lines between reality and fantasy.\nDevelop a mystery novel set in a secluded boarding school where a series of murders occur, forcing students and faculty to confront their dark secrets.\nCreate a thriller about a disgraced journalist who is drawn back into the world of espionage to uncover a dangerous conspiracy.\nWrite a contemporary literary fiction novel about a writer struggling with writer's block who finds inspiration in the lives of the people they observe in a local coffee shop.\nDevelop a young adult contemporary story about a group of friends who create a secret club to explore the abandoned buildings of their city, leading to unexpected discoveries.\nCreate a contemporary romance novel about two people from different worlds who fall in love while working together on a social impact project.\nWrite a horror novel about a group of friends who inherit a haunted mansion, uncovering a dark history and encountering terrifying supernatural entities.\nDevelop a romantic comedy about a travel blogger who falls in love with their tour guide while on a trip to a remote island.\nCreate a dystopian young adult novel about a society where citizens are ranked based on their social credit score, with those at the bottom fighting for a chance to rise up.\nWrite a science fiction western about a bounty hunter on a distant planet, facing dangerous outlaws and encountering alien civilizations.\nDevelop a historical fantasy novel about a young woman who discovers she is a descendant of a powerful sorceress and must fulfill a prophecy to save her world.\nCreate a contemporary magical realism story about a city where people develop extraordinary abilities after a mysterious event, leading to both wonder and chaos.\nWrite a post-apocalyptic thriller about a small group of survivors fighting for survival in a world overrun by mutated creatures.\nDevelop a historical mystery about a detective investigating a series of murders in Victorian London, uncovering a dark secret from the city's past.\nWrite a science fiction novella about a society where humans have uploaded their consciousnesses into a digital realm, exploring themes of identity, reality, and the meaning of existence.\nDevelop a short story about a planet colonized by humans where a mysterious alien species begins to communicate with the colonists, leading to unexpected consequences.\nCreate a science fiction thriller where a detective investigates a series of murders on a space station, uncovering a conspiracy involving a powerful corporation and a dangerous experiment.\nWrite a high fantasy novel about a young woman who discovers she is the last descendant of a powerful magical bloodline, destined to confront a rising evil.\nDevelop a fantasy adventure story featuring a group of mercenaries who are hired to protect a young princess on a perilous journey to fulfill a prophecy.\nCreate a low fantasy story set in a world where magic is slowly fading, following a young wizard who must find a way to restore it before it disappears entirely.\nWrite a historical fiction novel about a female pirate captain who challenges gender norms and builds a crew of diverse outcasts.\nDevelop a short story about a young African American soldier fighting for the Union Army during the Civil War, exploring themes of racism and courage.\nCreate a historical fiction thriller about a spy infiltrating the court of a powerful Renaissance ruler, uncovering a plot to overthrow the kingdom.\nWrite a psychological thriller about a woman who becomes obsessed with a true crime podcast, leading her to believe she is connected to the unsolved case.\nDevelop a mystery novel set in a small town where a series of mysterious disappearances occur, forcing the local sheriff to confront their own dark past.\nCreate a thriller about a former intelligence agent who is blackmailed into working for a shadowy organization, leading them into a dangerous world of espionage.\nWrite a contemporary literary fiction novel about a group of friends who reunite for a weekend getaway, only to discover a dark secret from their past.\nDevelop a young adult contemporary story about a high school student who starts a secret online support group for other struggling teens, finding solace and connection.\nCreate a contemporary romance novel about two people from different backgrounds who fall in love while working on a social justice project.\nWrite a horror novel about a group of college students who spend a weekend in a remote cabin, only to be terrorized by a malevolent entity.\nDevelop a romantic comedy about a workaholic who inherits a charming bed and breakfast, forcing them to slow down and embrace a new life.\nCreate a dystopian young adult novel about a society where people are assigned their careers at birth, with a rebellious protagonist questioning the system.\nWrite a science fiction western about a bounty hunter on a distant planet who teams up with an alien to bring down a ruthless criminal.\nDevelop a historical fantasy novel about a young woman who discovers she is a shapeshifter and must use her abilities to protect her people.\nCreate a contemporary magical realism story about a city where animals can talk, leading to unexpected friendships and challenges.\nWrite a post-apocalyptic thriller about a group of survivors who must navigate a dangerous wasteland to find a rumored safe haven.\nDevelop a historical mystery about a detective investigating a series of murders in ancient Rome, uncovering a conspiracy within the imperial court.\nWrite a science fiction novella about a crew of scientists who discover a habitable planet with an advanced alien civilization that has mysteriously vanished.\nDevelop a short story about a human colony on Mars where a new form of life emerges, forcing the colonists to reconsider their role on the planet.\nCreate a science fiction thriller where a detective investigates a series of murders on a space station, uncovering a conspiracy involving time travel and paradoxes.\nWrite a high fantasy novel about a young woman who discovers she is a dragon rider, destined to unite the divided kingdoms and defeat a powerful enemy.\nDevelop a fantasy adventure story featuring a group of outcasts who embark on a quest to find a legendary artifact capable of healing a dying world.\nCreate a low fantasy story set in a world where magic is a rare commodity, following a young woman who discovers she has a hidden talent for it.\nWrite a historical fiction novel about a female doctor working in a plague-ridden city, facing prejudice and danger while fighting to save lives.\nDevelop a short story about a young Native American who is forced to leave their tribe and adapt to life in a rapidly changing world.\nCreate a historical fiction thriller about a spy infiltrating the court of a powerful Ottoman sultan, uncovering a plot to assassinate the emperor.\nWrite a psychological thriller about a woman who becomes convinced that her deceased husband is still alive, leading her down a dangerous path.\nDevelop a mystery novel set in a remote mountain town where a series of mysterious deaths occur, forcing the local sheriff to confront a dark secret from the past.\nCreate a thriller about a former intelligence agent who is hired to protect a high-profile witness, only to find themselves caught in a deadly game of cat and mouse.\nWrite a contemporary literary fiction novel about a group of friends who reunite for a high school reunion, only to discover that their lives have taken unexpected turns.\nDevelop a young adult contemporary story about a transgender teen who is struggling to find acceptance and belonging in their community.\nCreate a contemporary romance novel about two people from different cultures who fall in love while working on a humanitarian project.\nWrite a horror novel about a group of friends who inherit an old family mansion, only to discover it is haunted by a malevolent spirit.\nDevelop a romantic comedy about a workaholic who moves to a small town to escape the city and finds love in unexpected places.\nCreate a dystopian young adult novel about a society where people are ranked based on their social media influence, with a rebellious protagonist fighting for equality.\nWrite a science fiction western about a bounty hunter on a distant planet who teams up with a robot to bring down a ruthless criminal.\nDevelop a historical fantasy novel about a young woman who discovers she is a descendant of a powerful witch and must use her magic to save her kingdom.\nCreate a contemporary magical realism story about a city where objects come to life, leading to chaos and wonder.\nWrite a post-apocalyptic thriller about a group of survivors who must navigate a dangerous wasteland to find a rumored safe haven.\nDevelop a historical mystery about a detective investigating a series of murders in ancient Egypt, uncovering a conspiracy involving the pharaoh.\nWrite a science fiction thriller about a detective investigating a series of murders on a space station, uncovering a conspiracy involving time travel and paradoxes.\n"
  },
  {
    "path": "pyopenagi/data/agent_tasks/example/tech_support_agent_task.txt",
    "content": "My Windows 10 laptop is running extremely slow, even after restarting and closing unnecessary programs. I've noticed high disk usage, but I don't know how to fix it.\nI keep getting a blue screen error with the stop code \"INACCESSIBLE_BOOT_DEVICE\" on my newly installed SSD. I've tried reinstalling Windows, but the issue persists.\nMy MacBook Pro is freezing randomly, especially when running resource-intensive applications like video editing. I've checked for software updates and malware but haven't found a solution.\nMy HP LaserJet Pro MFP M148fw printer is connected to my Wi-Fi network, but it won't print documents. I've tried reinstalling the drivers and restarting both the printer and router.\nMy iPhone 13 Pro Max is unable to connect to any Wi-Fi networks, but mobile data works fine. I've tried forgetting the networks and restarting the phone.\nMy Gmail account keeps syncing endlessly on my Samsung Galaxy S22. I've removed and re-added the account, but the problem continues.\nI'm unable to connect to my company's Cisco AnyConnect VPN. I've installed the latest VPN client and checked my network settings, but I still get an error message.\nMy Seagate external hard drive is not showing up in File Explorer. I've tried different USB ports and checked disk management, but it's still not recognized.\nI accidentally deleted my entire Documents folder on my Windows 11 PC. I've tried using the Recycle Bin and data recovery software, but I haven't been able to recover the files.\nMy Logitech C920 webcam is producing a grainy and blurry image during Zoom meetings. I've updated the camera drivers and checked the video settings, but the quality hasn't improved.\nMicrosoft Word keeps crashing when I try to insert a large image into a document. I've tried saving the document in different formats and restarting Word, but the issue persists.\nI'm unable to install Adobe Photoshop CC 2023 on my new M1 MacBook Air. I've downloaded the correct installer and followed the installation instructions, but it keeps failing.\nExcel formulas are returning incorrect results, even after double-checking the syntax and cell references. I've tried recalculating the worksheet and saving it in different formats, but the problem remains.\niTunes is not recognizing my iPhone 14 Pro, even though I've tried restarting both devices and reinstalling iTunes. I need to sync my music and contacts.\nI'm getting a \"file is corrupt or damaged\" error when trying to open PDF files in Adobe Acrobat Reader DC. I've tried repairing the installation and converting the PDFs to other formats, but the issue continues.\nThe audio and video are out of sync in VLC Media Player when playing certain MKV files. I've tried changing the playback settings and updating the video codecs, but the problem persists.\nMy Norton Antivirus is blocking access to legitimate websites, even after adding them to the trusted sites list. I've tried reinstalling the antivirus software, but the issue remains.\nI'm having trouble setting up multiple email accounts in Outlook for Mac. I've followed the online instructions, but I keep getting an error message.\nMy Google Chrome browser is constantly redirecting me to ad-filled websites. I've installed ad-blocking extensions and scanned for malware, but the redirects continue.\nI'm getting a \"disc read error\" message when trying to install the latest Call of Duty game on my PlayStation 5. I've cleaned the disc and tried reinstalling the game, but the issue persists.\nMy Dell XPS 13 laptop battery is draining much faster than usual, even when on power-saving mode. I've calibrated the battery and checked for background apps, but the issue persists.\nThe screen on my LG 27GN950 monitor is flickering intermittently, especially when displaying dark scenes. I've tried different cables and input sources, but the flickering continues.\nSeveral keys on my Logitech G513 keyboard are sticking, making it difficult to type. I've cleaned the keyboard and tried different USB ports, but the problem persists.\nMy Razer Deathadder V3 Pro mouse cursor is jumping randomly, making it impossible to use accurately. I've tried updating the mouse drivers and changing the battery, but the issue remains.\nMy custom-built gaming PC is overheating, causing it to throttle and crash during demanding games. I've cleaned the fans and applied new thermal paste, but the temperature is still high.\nThe fans in my HP Pavilion desktop are making a loud, grinding noise. I've checked for dust buildup and tried lubricating the fan bearings, but the noise continues.\nMy MacBook Pro charger is only charging the laptop slowly, and it doesn't hold a charge for very long. I've tried different outlets and charging cables, but the issue persists.\nThe left speaker on my Bose Companion 500 system is producing a distorted sound. I've checked the speaker cables and adjusted the audio settings, but the problem remains.\nMy iMac is not turning on at all, even after trying different power outlets and resetting the SMC. I've checked for any visible damage to the power cord.\nThere's a burning smell coming from my PS5 console. I've turned it off immediately and unplugged it, but I'm concerned about potential damage.\nI need a reliable antivirus program for my Windows 11 gaming PC that won't impact game performance. I'm looking for something with strong malware protection and real-time scanning.\nI'm a hobbyist video editor and need software that can handle 4K footage without lagging. I'm looking for something user-friendly with good color correction tools.\nI need a cloud storage solution with robust security features to backup important documents and photos. I'm looking for a plan with ample storage and fast upload/download speeds.\nI need software to access my work computer remotely from my personal laptop. I'm looking for a solution that is easy to set up and provides a secure connection.\nI accidentally deleted important files from my external hard drive and need software to recover them. I'm looking for a tool with a high recovery success rate and user-friendly interface.\nI need a backup solution for my entire computer system, including operating system, applications, and data. I'm looking for a reliable and automated solution.\nMy computer is running slowly, even with ample RAM and storage. I need software to optimize system performance and free up disk space.\nI need software to edit photos for social media and create basic designs. I'm looking for a free or low-cost option with a user-friendly interface.\nI have a large collection of video files in different formats and need to convert them to MP4 for playback on my smart TV. I'm looking for software that supports batch conversion and maintains video quality.\nI have multiple online accounts with complex passwords and need a way to manage them securely. I'm looking for a password manager that generates strong passwords and autofills login information.\nMy Windows 10 laptop is stuck on the \"Preparing to configure updates\" screen for hours. I've tried restarting the computer and running the Windows Update troubleshooter, but it's still stuck.\nI'm unable to install the latest iOS update on my iPhone 13 Pro Max due to insufficient storage. I've deleted unnecessary apps and photos, but there's still not enough space.\nMy iPad Pro is stuck on the Apple logo during a software update. I've tried force restarting the device, but it's still unresponsive.\nI need to update the drivers for my NVIDIA RTX 3080 graphics card to improve game performance. I've downloaded the latest drivers from the NVIDIA website, but the installation keeps failing.\nMy HP LaserJet Pro MFP M148fw printer is displaying an error message saying the firmware is outdated. I've tried updating through the printer's control panel and HP Smart app, but it's unsuccessful.\nI want to update my Samsung Smart TV to the latest software version to access new features. I've checked for updates through the TV settings, but there's no available update.\nMy Android phone is running an older version of the operating system and I'm concerned about security vulnerabilities. I've checked for updates through the system settings, but there's no available update.\nMy TP-Link Archer AX5000 router's firmware is outdated, and I'm experiencing frequent disconnections. I've tried updating the firmware through the router's web interface, but it's unsuccessful.\nI want to update my MacBook Pro to the latest macOS version to improve performance and security. I've checked for updates through the System Preferences, but the update is taking a long time to download.\nMy PlayStation 5 console is asking for a system software update, but the download keeps failing. I've tried restarting the console and checking the internet connection, but the issue persists.\nMy home Wi-Fi network is slow, especially during peak usage times. I've tried restarting the router and checking for interference, but the speeds haven't improved.\nI'm unable to connect to my neighbor's guest Wi-Fi network, even though other devices can connect successfully. I've tried entering the correct password and forgetting the network, but it still won't connect.\nMy wireless headphones keep disconnecting from my laptop, even when sitting close by. I've tried updating the headphone firmware and restarting both devices, but the issue persists.\nI'm getting a weak Wi-Fi signal in my basement, making it difficult to stream videos without buffering. I've tried using a Wi-Fi extender, but it hasn't helped much.\nMy internet connection keeps dropping randomly throughout the day, causing interruptions to online activities. I've checked for modem and router issues, but the problem continues.\nI can't access certain websites like Google or YouTube, while other websites load normally. I've tried clearing browser cache and cookies, but the issue persists.\nOnline gaming is experiencing high latency and packet loss, leading to lag and disconnections. I've tried closing other applications and prioritizing gaming traffic, but the problem continues.\nMy internet connection is slow when multiple devices are connected. I've tried upgrading my router to a dual-band model and optimizing network settings, but the issue persists.\nMy router keeps restarting unexpectedly, causing internet outages. I've checked for overheating and firmware updates, but the problem continues.\nI'm receiving a large volume of spam emails, despite having spam filters enabled. I've tried creating new email accounts and using different email clients, but the spam continues.\nI just built a new PC and am having trouble installing the CPU cooler. The instructions are unclear, and I'm worried about damaging the CPU.\nI'm trying to connect my external hard drive to my PS4, but it's not being recognized. I've tried different USB ports and formatting the drive, but it still doesn't work.\nI want to set up a dual monitor setup for my MacBook Pro, but one of the monitors is not displaying correctly. I've tried different cables and display settings, but the issue persists.\nI'm trying to connect my wireless headphones to my TV, but I can't find the correct pairing settings. I've tried using the TV's remote and headphone settings, but it still won't connect.\nI need to replace the battery in my laptop, but I'm not sure which one to buy or how to install it. I've checked the laptop's model number, but I'm still unsure.\nI'm trying to install a new graphics card in my PC, but I'm getting a black screen after booting up. I've checked the power supply and reseated the graphics card, but the issue persists.\nI want to upgrade the RAM in my desktop PC, but I'm not sure which type of RAM is compatible. I've checked the motherboard manual, but the information is confusing.\nI'm trying to connect my smartphone to my car's stereo system using Bluetooth, but it keeps disconnecting. I've tried forgetting the pairing and reconnecting, but the issue persists.\nI want to build a custom gaming PC, but I'm overwhelmed by the number of components available. I need help choosing the right CPU, GPU, motherboard, and other parts.\nI'm trying to install a new SSD in my laptop, but I'm not sure how to clone my existing operating system to the new drive. I've tried using cloning software, but it's not working correctly.\nMy iPhone 14 Pro keeps overheating, even when idle. I've closed background apps and updated the software, but the issue persists.\nMy Samsung Galaxy S23 Ultra's battery is draining rapidly, despite optimizing power settings. I've checked for background apps and updated the software, but the problem continues.\nMy MacBook Air's trackpad is unresponsive in certain areas. I've tried restarting the computer and recalibrating the trackpad, but the issue remains.\nMy Sony PlayStation 5 controller's left joystick is drifting, making it difficult to play games accurately. I've tried recalibrating the controller and cleaning the joystick, but the problem persists.\nMy Nintendo Switch's Joy-Con controllers are disconnecting frequently, even when in handheld mode. I've tried re-pairing the controllers and updating the system software, but the issue continues.\nMy Amazon Echo Dot is not responding to voice commands consistently. I've tried resetting the device and updating the Alexa app, but the problem persists.\nMy Apple Watch Series 8 is not tracking my heart rate accurately. I've tried tightening the watch band and restarting the device, but the issue remains.\nMy Fitbit Charge 5 is not syncing with my smartphone, even though Bluetooth is enabled. I've tried restarting both devices and reinstalling the Fitbit app, but the problem continues.\nMy DJI Mavic Air 2 drone's camera is producing blurry footage, even in good lighting conditions. I've tried cleaning the camera lens and updating the drone's firmware, but the issue persists.\nMy Ring doorbell camera's video quality is poor, and the night vision is not working properly. I've tried adjusting the camera settings and restarting the device, but the problem persists.\nMy computer is running slowly, even with 16GB of RAM and an SSD. I've tried closing unnecessary programs and running disk cleanup, but it's still sluggish.\nMy laptop's battery drains quickly, even when on power-saving mode and with minimal use. I've checked for background apps and updated drivers, but the issue persists.\nMy computer freezes frequently when running multiple programs or demanding applications. I've tried increasing virtual memory and disabling unnecessary startup programs, but the problem continues.\nI keep getting a blue screen error with the stop code \"SYSTEM_THREAD_EXCEPTION_NOT_HANDLED\". I've tried updating drivers and running a memory test, but the issue persists.\nMy computer crashes with a blue screen error after installing a new graphics card driver. I've rolled back the driver and reinstalled it, but the problem continues.\nMy external hard drive is making clicking noises and is no longer recognized by my computer. I've tried connecting it to different USB ports, but it still doesn't work.\nMy laptop's touchpad is unresponsive in certain areas, making it difficult to use. I've tried reinstalling the touchpad drivers and recalibrating the device, but the issue persists.\nMy computer's power supply unit (PSU) is making a high-pitched noise and the computer is frequently restarting. I've checked for overheating and dust buildup, but the problem continues.\nMy antivirus software is blocking legitimate programs, causing them to crash or not function properly. I've tried adding exceptions to the antivirus, but the issue persists.\nTwo programs are conflicting, causing system instability. I've tried running them in compatibility mode and updating both programs, but the problem continues.\nMy Wi-Fi connection keeps dropping, even though the router signal is strong. I've tried restarting the router and checking for interference, but the problem persists.\nI'm unable to connect to specific websites, while others load normally. I've cleared browser cache and cookies, but the issue remains.\nMy internet speed is much slower than advertised by my ISP. I've tried connecting directly to the modem and running speed tests, but the results are still slow.\nMy computer won't boot up and displays a black screen with a blinking cursor. I've tried resetting the CMOS and checking for loose cables, but the issue persists.\nI'm receiving error messages when trying to install a new program. I've tried running the installer as administrator and checking for disk space, but the problem continues.\nMy printer is printing blank pages or garbled text. I've tried reinstalling the printer drivers and checking the ink levels, but the issue persists.\nMy computer is making strange clicking noises from the hard drive. I've backed up my data, but I'm worried about data loss.\nMy laptop screen is flickering and has dark spots. I've tried adjusting the display settings and checking for loose cables, but the issue persists.\nMy wireless mouse keeps disconnecting randomly, even when close to the computer. I've tried changing batteries and re-pairing the mouse, but the problem continues.\nMy keyboard keys are sticking or not responding consistently. I've tried cleaning the keyboard and checking for driver issues, but the problem persists.\n"
  },
  {
    "path": "pyopenagi/data/agent_tasks/example/travel_agent_task.txt",
    "content": "I want to take a trip to Paris, France from July 4th to July 10th, 2024, and I am traveling from New York City. Help me plan this trip.\nI want to take a trip to San Francisco, California from May 10th to May 15th, 2024, and I am traveling from Miami, Florida. Help me plan this trip.\nI want to take a trip to Tokyo, Japan from September 1st to September 10th, 2024, and I am traveling from Los Angeles, California. Help me plan this trip.\nI want to take a trip to Austin, Texas from March 15th to March 20th, 2024, and I am traveling from Chicago, Illinois. Help me plan this trip.\nI want to take a trip to Sydney, Australia from December 20th to December 30th, 2024, and I am traveling from Seattle, Washington. Help me plan this trip.\nI want to take a trip to Denver, Colorado from August 5th to August 10th, 2024, and I am traveling from Houston, Texas. Help me plan this trip.\nI want to take a trip to Rio de Janeiro, Brazil from February 1st to February 10th, 2024, and I am traveling from Atlanta, Georgia. Help me plan this trip.\nI want to take a trip to Portland, Oregon from June 20th to June 25th, 2024, and I am traveling from Phoenix, Arizona. Help me plan this trip.\nI want to take a trip to Rome, Italy from May 15th to May 22nd, 2024, and I am traveling from Boston, Massachusetts. Help me plan this trip.\nI want to take a trip to Orlando, Florida from July 5th to July 12th, 2024, and I am traveling from Philadelphia, Pennsylvania. Help me plan this trip.\nI want to take a trip to Berlin, Germany from August 14th to August 21st, 2024, and I am traveling from San Francisco, California. Help me plan this trip.\nI want to take a trip to Las Vegas, Nevada from April 10th to April 15th, 2024, and I am traveling from Denver, Colorado. Help me plan this trip.\nI want to take a trip to Cairo, Egypt from November 10th to November 20th, 2024, and I am traveling from Dallas, Texas. Help me plan this trip.\nI want to take a trip to Nashville, Tennessee from September 10th to September 15th, 2024, and I am traveling from Indianapolis, Indiana. Help me plan this trip.\nI want to take a trip to London, United Kingdom from June 7th to June 14th, 2024, and I am traveling from Washington D.C. Help me plan this trip.\nI want to take a trip to Honolulu, Hawaii from October 5th to October 12th, 2024, and I am traveling from San Diego, California. Help me plan this trip.\nI want to take a trip to Bangkok, Thailand from April 1st to April 10th, 2024, and I am traveling from Seattle, Washington. Help me plan this trip.\nI want to take a trip to Chicago, Illinois from May 10th to May 15th, 2024, and I am traveling from New York City. Help me plan this trip.\nI want to take a trip to Barcelona, Spain from July 10th to July 17th, 2024, and I am traveling from Miami, Florida. Help me plan this trip.\nI want to take a trip to Dallas, Texas from November 15th to November 20th, 2024, and I am traveling from Orlando, Florida. Help me plan this trip.\nI want to take a trip to Athens, Greece from May 1st to May 10th, 2024, and I am traveling from Denver, Colorado. Help me plan this trip.\nI want to take a trip to New Orleans, Louisiana from February 20th to February 25th, 2024, and I am traveling from Atlanta, Georgia. Help me plan this trip.\nI want to take a trip to Dubai, UAE from October 15th to October 25th, 2024, and I am traveling from Detroit, Michigan. Help me plan this trip.\nI want to take a trip to Los Angeles, California from March 1st to March 5th, 2024, and I am traveling from Houston, Texas. Help me plan this trip.\nI want to take a trip to Dublin, Ireland from June 1st to June 8th, 2024, and I am traveling from Boston, Massachusetts. Help me plan this trip.\nI want to take a trip to Austin, Texas from September 5th to September 10th, 2024, and I am traveling from Phoenix, Arizona. Help me plan this trip.\nI want to take a trip to Hong Kong from December 1st to December 10th, 2024, and I am traveling from San Jose, California. Help me plan this trip.\nI want to take a trip to Seattle, Washington from July 15th to July 20th, 2024, and I am traveling from Minneapolis, Minnesota. Help me plan this trip.\nI want to take a trip to Amsterdam, Netherlands from July 1st to July 8th, 2024, and I am traveling from Indianapolis, Indiana. Help me plan this trip.\nI want to take a trip to Miami, Florida from January 5th to January 10th, 2024, and I am traveling from Philadelphia, Pennsylvania. Help me plan this trip.\n"
  },
  {
    "path": "pyopenagi/data/agent_tasks/example/travel_planner_agent_task.txt",
    "content": "Please plan a trip for me starting from Sarasota to Chicago for 3 days, from March 22nd to March 24th, 2022. The budget for this trip is set at $1,900.\nSeeking assistance to develop a travel itinerary for a 3-day trip for one person. The trip will begin in Washington, with Tampa as the destination from March 25th through March 27th, 2022. The budget for this journey is $1,800.\nPlease create a travel plan that starts in Charleston and leads to St. Louis over a span of three days, from March 16th to March 18th, 2022. This trip is designed for one individual with a budget of $900.\nPlease design a travel plan that departs from Jacksonville, heading for Norfolk for 3 days spanning from March 3rd to March 5th, 2022. The journey is designed for one person, with a budget of $1,900.\nPlease create a travel itinerary for a solo traveler departing from Jacksonville and heading to Los Angeles for a period of 3 days, specifically from March 25th to March 27th, 2022. The budget for this trip is now set at $2,400.\nPlease help me plan a travel itinerary from Phoenix to Billings, spanning 3 days from March 18th to March 20th, 2022. The budget for this trip is capped at $2,100.\nPlease arrange a travel plan for one person from St. Louis to Oklahoma City. The trip should span 3 days from March 17th to March 19th, 2022 within a budget of $700.\nPlease help me build a travel plan that departs from Denver to Medford, for a duration of 3 days from March 3rd to March 5th, 2022. This trip is for one person with a budget of $1,700.\nPlease create a 3-day travel plan starting from Charleston to New York. The planned dates of travel are from March 17th to March 19th, 2022, with a travel budget of $1,700.\nPlease create a 3-day travel itinerary for one person, beginning in Dallas and ending in Indianapolis between March 25th and March 27th, 2022. My budget for this trip is $1,300.\nPlease help in creating a travel itinerary leaving Chicago and heading for Ogdensburg. The plan will cover 3 days, from March 20th to March 22nd, 2022, for one person with a total budget of $1,500.\nCould you help create a 3-day travel plan for one person? The journey starts in Long Beach and the destination is Dallas. The travel dates are from March 24th to March 26th, 2022, with a budget of $1,900.\nPlease create a travel plan that begins in Huntsville and ends in Indianapolis, spanning 3 days from March 27th to March 29th, 2022, for a lone traveler. The budget for this trip is set to $1,200.\nCould you please help create a travel plan that departs from Bozeman and arrives in Los Angeles? I plan to visit for 3 days from March 20th to March 22nd, 2022. My budget for this trip is $1,900.\nPlease create a 3-day travel plan for an individual starting in Atlanta and going to San Diego from March 5th to March 7th, 2022, with a budget of $3,100.\nCould you design a travel itinerary that begins in Baltimore and ends in Milwaukee over the course of 3 days, specifically from March 10th to March 12th, 2022? The budget for this trip is $900.\nCould you help me arrange a 3-day trip for one person, which starts in Lihue and ends in San Francisco, from March 27th to March 29th, 2022? I have a budget of $2,300 for this trip.\nPlease create a travel plan for me starting in Punta Gorda and heading to Plattsburgh for 3 days, from March 7th to March 9th, 2022. The budget for this trip is $900.\nKindly assist in creating a travel plan for a solo traveler heading from Appleton to Denver. The trip should span three days, from March 1st to March 3rd, 2022, with a budget set at $1,200.\nPlease devise a travel plan that departs from Little Rock and heads to Phoenix spanning from March 24th to March 26th, 2022. This trip is intended for one person and has a new budget set to $1,300.\nPlease provide a travel plan departing from Savannah and heading to Newark for 3 days, from March 23rd to March 25th, 2022, with a budget of $800.\nPlease craft a travel plan starting from Dallas and concluding in Tallahassee, lasting 3 days from March 23rd through March 25th, 2022. The plan is for a single traveler with a budget constraint of $1,100.\nCould you assist in creating a travel plan for me? I plan to depart Myrtle Beach and head towards Syracuse. The duration of my trip is 3 days, specifically from March 23rd to March 25th, 2022, and my budget for this trip is $700.\nI need assistance with arranging a 3-day trip beginning in Memphis and heading to Los Angeles, which happens from March 15th until March 17th, 2022. The budget allocated for this trip is $1,600. Can you help with this?\nCould you help with a travel itinerary that begins in Wilmington and ends in New York, lasting three days from March 12th to March 14th, 2022? This trip is for an individual, with a budget of $1,500.\nPlease develop a 3-day travel plan leaving Baltimore and landing in Milwaukee for one person from March 29th to March 31st, 2022, with a total budget of $1,200.\nCould you create a travel plan for me? I'll be departing from Tampa and heading to Austin for 3 days from March 5th to March 7th, 2022. My budget for this trip is $1,800.\nPlease help me outline a travel plan that commences in Charleston and leads to St. Louis for a duration of 3 days, specifically from March 8th to March 10th, 2022. I have allocated a budget of $900 for this trip.\nPlease create a 3-day travel plan that starts in Miami and ends in Des Moines, taking place from March 8th to March 10th, 2022. The travel plan is for one person with a budget of $1,900.\nPlease help me prepare a 3-day travel plan from Atlanta to New Orleans for one person. The trip will take place from March 13th to March 15th, 2022, and the budget is $800.\nPlease draft a travel plan that departs from Belleville and heads to Las Vegas for 3 days, from March 27th to March 29th, 2022. The budget for the journey should not exceed $1,900.\nPlease organize a travel plan for one, leaving Dallas and heading to Pensacola. The trip will be 3 days long, starting from March 29th and ending on March 31st, 2022. The budget for this journey is set at $1,400.\nPlease create a travel itinerary that starts in Salt Lake City and ends in Fresno for a single traveler. The trip will last for 3 days, from March 15th through March 17th, 2022. The travel budget should be capped at $900.\nKindly assist in plotting a travel plan starting from Houston to San Diego. This trip is set to last 3 days from March 9th to March 11th, 2022, accommodated by a budget of $2,400.\nCould you help draft a travel plan for one person, leaving from Minneapolis to Baltimore for 3 days, from March 11th to March 13th, 2022? The total budget for this trip is $1,400.\nPlease construct a 3-day travel itinerary from Kansas City to Newark, specifically from March 9th to March 11th, 2022. The trip is for one individual and should not exceed a budget of $1,300.\nCould you help create a travel plan that starts in Atlanta and ends in Bozeman, taking place over 3 days from March 25th to March 27th, 2022? The travel budget at hand is $1,900.\nPlease help me create a travel plan departing from Atlanta and heading to Minneapolis for 3 days, from March 5th to March 7th, 2022, within a budget of $1,900.\nCan you assist me in creating a 3-day travel plan departing from Honolulu, heading to Sacramento from March 10th to March 12th, 2022? I will be traveling alone, and my budget is set at $2,000.\nCould you help organize a travel plan from Moline to Dallas for the duration of 3 days, specifically from March 25th to March 27th, 2022? This travel plan is intended for a single individual and should operate within a budget of $1,600.\nCould you devise a travel plan for one person departing from San Francisco and heading to Kahului for 3 days, from March 25th through March 27th, 2022, with a budget of $2,900?\nPlease formulate a travel plan for one person departing from Phoenix to Des Moines spanning from March 6th to March 8th, 2022. The budget for this trip is set to be $600.\nPlease arrange a 3-day travel plan for one person, departing from Tampa and heading to Phoenix. The trip should take place from March 24th to March 26th, 2022, within a budget of $1,800.\nCan you assist in creating a travel itinerary for 1 person leaving from Scranton to visit Newark for a span of 3 days, specifically from March 24th to March 26th, 2022, with a budget of $1,600?\nCan you assist me in crafting a 3-day travel itinerary departing from Reno and heading to Austin? The travel dates are from March 4th to March 6th, 2022. This trip will be for one person, and we have allocated a budget of $2,300 for this trip.\nCould you create a 3-day travel plan for one person, departing from Houston and heading to Punta Gorda from March 20th to March 22nd, 2022, with a budget of $1,700?\nCould you create a travel plan departing from Gulfport to Charlotte for a 3-day trip from March 5th to 7th, 2022 for an individual? Our budget is now set at $1,200.\nCould you plan a trip for me from Raleigh to Dallas for 3 days, from March 22nd to March 24th, 2022? I'm traveling solo, and my set budget is $1,500.\nCould you structure a 3-day travel plan for one person beginning in Kansas City and ending in Orlando from March 7th to March 9th, 2022, with a budget cap at $1,800? Please note that there are no specific requirements for accommodations, cuisine, or transportation.\nCan you help me create a travel plan departing from Tulsa and heading to Phoenix? The trip should last 3 days, starting on March 6th and ending on March 8th, 2022. Please keep the budget under $1,700.\nPlease devise a travel plan that sees me departing from Phoenix and heading to Kahului for 3 days, specifically from March 1st to March 3rd, 2022. My budget for this solo trip is set at $2,900.\nPlease curate a 3-day travel plan for a solo traveler from Tulsa to Houston from March 23rd to March 25th, 2022, with a total travel budget of $1,000.\nCould you help me plan a trip from Everett to San Francisco? The trip will span 3 days, from March 21st to March 23rd, 2022. I have a budget of $500 set for this journey.\nPlease help me plan a 3-day trip from Omaha to Seattle, starting from March 17th to March 19th, 2022. The trip is for a solo traveler and the budget is $1,700.\nKindly assist in creating a travel plan that starts from Gainesville and ends in Charlotte, taking place across 3 days from March 20th to March 22nd in 2022. The trip is for one person, with a budget of $1,100.\nPlease create a travel plan from Los Angeles to Denver for one person, staying for 3 days from March 3rd to March 5th, 2022. The budget for the trip is $1,800.\nPlease create a 3-day travel itinerary for one person, departing from Houston and heading to Reno from March 11th to March 13th, 2022, with a budget of $2,200.\nCan you assist me in planning a 3-day solo trip from Los Angeles to Reno between March 21st and March 23rd, 2022? My budget is set at $1,200 for this journey.\nCould you create a travel plan for a single person, leaving from Knoxville and heading to Denver for a duration of 3 days, from March 10th to March 12th, 2022, with a revised maximum budget of $2,100?\nCould you create a travel plan for me? I will be departing from Boston and heading to Washington. The trip will last for 3 days, from March 9th to March 11th, 2022. The budget for this trip is $1,000.\nBegin in Minneapolis, and plot a 3-day journey to San Diego covering one city between March 10th and March 12th, 2022. The trip, designed for one person, has a total budget of $2,800.\nPlease help me arrange a 3-day trip from Ithaca to Philadelphia starting from March 1st to March 3rd, 2022, for one person. The budget for the trip is now set at $1,600.\nCould you design a 3-day travel plan for one person, departing from Denver to Oakland? The trip will span from March 26th to March 28th, 2022, with a budget constraint of $1,300.\nCould you help me plan a trip from New York to Ponce, taking place over 3 days from March 28th to March 30th, 2022? The trip is for a single person, and the available budget is $2,200.\nCould you help me create a 3-day travel plan that begins in Bangor and ends in Newark? The travel dates are from March 18th to March 20th, 2022, and the budget for the trip is set at $1,600. The plan is for one person.\nCould you create a travel plan for me? I'll be departing from Minneapolis and heading to Jacksonville for 3 days from March 27th to March 29th, 2022. I have set my budget at $1,800.\nPlease arrange a 3-day travel plan from Fort Lauderdale to Charlotte Amalie. The travel dates are from March 16th to March 18th, 2022. The budget for this trip is capped at $2,000.\nPlease help me with a travel plan that departs from Panama City to Chicago for a duration of three days from March 12th to March 14th, 2022. I am looking for the plan to be designed for one individual with a budget of $1,800.\nPlease create a travel plan beginning in Washington, DC and heading to Cleveland for a 3-day journey from March 5th to 7th, 2022. The travel budget is set at $1,400.\nCould you assist in formulating a travel plan that starts in Myrtle Beach and heads to Fort Lauderdale, lasting for 3 days from March 16th to March 18th, 2022? The budget for this trip is set at $1,500.\nCould you assist me in creating a travel plan for a 3-day journey from Houston to Sacramento, taking place from March 29th to March 31st, 2022? My budget for this trip is $1,400.\nCould you create a travel itinerary for a single traveler, departing from Charleston and heading to Cincinnati for 3 days, from March 20th to March 22nd, 2022? The plan should fit within a budget of $600.\nCould you provide a trip plan where I depart from Nashville heading towards Austin for a 3-day trip from March 18th to March 20th, 2022? The budget for this trip has been set at $1,800.\nCould you help me plan a 3-day trip departing from Las Vegas and heading to Minneapolis from March 11th to March 13th, 2022? I am traveling alone with a budget of $1,500.\nCould you create a travel plan that departs from Pensacola and heads to Dallas, spanning 3 days from March 8th to March 10th, 2022? The plan is meant for a single traveler with a set budget of $1,300.\nPlease develop a three-day travel itinerary for one person, starting from New Orleans and ending in Houston. The journey will span from March 4th until March 6th, 2022. We have a budget of $1,000 to cover all costs.\nPlease help in planning a trip from San Francisco to Minneapolis for 1 person. The trip should span 3 days, from March 25th to March 27th, 2022, with a set budget of $2,100.\nCould you help create a travel itinerary starting from Fort Lauderdale to Kansas City for a solo traveler? The trip will span over 3 days, from March 23rd to March 25th, 2022. The budget for the trip is set at $1,300.\nCould you help create a travel plan where I depart from San Francisco headed to Tampa for a duration of 3 days, specifically from March 24th to March 26th, 2022? The budget for this trip is $2,900.\nPlease help me create a travel plan departing Charlotte for Akron that lasts 3 days, from March 8th to March 10th, 2022, with a budget of $1,000.\nCan you help put together a travel plan for a single passenger leaving Tampa towards Cleveland for a duration of 3 days, starting from March 2nd up until March 4th, 2022? Please make sure the budget does not exceed $1,800.\nCould you assist me in creating a three-day travel plan? The journey begins in San Luis Obispo and concludes in Phoenix. The trip is scheduled from March 11th to March 13th, 2022. The allocated budget for this trip is now $1,000.\nKindly create a travel plan starting from Washington and heading towards Montgomery for a period of 3 days from March 2nd to March 4th, 2022. The travel plan has a budget of $500.\nCould you help create a 3-day travel arrangement for a solo traveler, starting in Chicago and heading to El Paso from March 22nd to March 24th, 2022? The budget for this trip is set at $1,800.\nPlease create a 3-day travel plan departing from Denver and heading to Fort Lauderdale, spanning the dates of March 19th to March 21st, 2022, for one person with a budget of $2,000.\nPlease assist in crafting a 3-day travel itinerary beginning in San Antonio and culminating in Tampa. The journey is scheduled from March 15th to March 17th, 2022. The budget for this trip has been set at $1,200.\nPlease create a 3-day travel plan starting in Atlantic City and heading to Miami from March 21st to March 23rd, 2022 for a single traveler, with a maximum budget of $900.\nCould you create a travel itinerary for me starting in Sacramento and heading to Minneapolis? This trip should be 3 days long, from March 7th to March 9th, 2022 with a budget of $1,900.\nPlease help me create a travel plan starting from Chicago and ending in Sacramento, spanning 3 days from March 2nd to March 4th, 2022. The budget for this solo journey is set at $2,000.\nPlease help me plan a travel itinerary from Oakland to Eugene that lasts for 3 days, from March 18th to March 20th, 2022, with a budget of $1,100.\nPlease prepare a travel itinerary beginning from Newburgh and heading to Tampa for the duration of 3 days, from March 1st to March 3rd, 2022. The travel plan is for a single individual with a budget of $1,500.\nPlease help me arrange a 3-day travel plan departing from Grand Rapids and heading towards Tampa from March 13th to March 15th, 2022. This trip is for one person with a budget set at $1,900.\nPlease create a travel plan for a trip starting in Chattanooga and heading to Atlanta. The trip will last for 3 days, from March 26th to March 28th, 2022. This trip is for one person and has a budget of $800.\nCan you assist me in mapping out a 3-day voyage from Manchester to Philadelphia occurring between March 19th and March 21st, 2022? I will be traveling alone with a budget of $1,700.\nCan you help design a travel plan departing from Detroit and heading to Mosinee for 3 days, specifically from March 24th to March 26th, 2022, with a budget of $1,100?\nPlease create a travel plan for a 3-day trip from Houston to Boise for one person from March 26th to March 28th, 2022. The budget for this journey is set at $1,700.\nCould you please create a 3-day travel plan for one individual, which starts from Bangor and ends in Chicago, covering the dates from March 19th to March 21st, 2022, with a total budget of $1,900?\nCould you help me craft a travel itinerary starting from Philadelphia to Cleveland, encompassing 3 days from March 25th to March 27th, 2022? The travel goal is to visit 1 city within this period, and the budget allocated for this trip is $1,500.\nCould you create a travel plan for me where I depart from Syracuse and head to Denver for 3 days, starting from March 22nd to March 24th, 2022, with a budget of $2,200?\nPlease help me create a travel plan departing from Hilton Head and heading to Philadelphia for a period of 3 days, from March 16th to March 18th, 2022. The budget for this trip is now $1,500.\n"
  },
  {
    "path": "pyopenagi/manager/manager.py",
    "content": "# agent_manager.py\n\nimport os\nimport json\nimport base64\nimport subprocess\nimport sys\nfrom typing import List, Dict\nimport requests\nfrom pathlib import Path\n\nclass AgentManager:\n    def __init__(self, base_url: str):\n        self.base_url = base_url\n        # self.cache_dir = Path(user_cache_dir(\"agent_manager\", \"AIOS\"))\n        self.cache_dir = Path('/Users/rama2r/AIOS/agenthub/cache')\n        self.cache_dir.mkdir(parents=True, exist_ok=True)\n\n    def upload_agent(self, author: str | None, name: str | None, version: str | None, folder_path: str):\n        agent_files = self._get_agent_files(folder_path)\n        metadata = self._get_agent_metadata(folder_path)\n\n\n        payload = {\n            \"author\":  metadata.get(\"meta\", {}).get('author', author),\n            \"name\":  metadata.get('name', name),\n            \"version\": metadata.get(\"meta\", {}).get('version', version),\n            \"license\": metadata.get(\"license\", \"Unknown\"),\n            \"files\": agent_files,\n            \"entry\": metadata.get(\"build\", {}).get(\"entry\", \"main.py\"),\n            \"module\": metadata.get(\"build\", {}).get(\"module\", \"Agent\")\n        }\n\n        response = requests.post(f\"{self.base_url}/api/upload\", json=payload)\n        response.raise_for_status()\n        print(f\"Agent {payload.get('author')}/{payload.get('name')} (v{payload.get('version')}) uploaded successfully.\")\n\n    def download_agent(self, author: str, name: str, version: str = \"latest\") -> str:\n        cache_path = self._get_cache_path(author, name, version)\n        if cache_path.exists():\n            print(f\"Using cached version of {author}/{name} (v{version})\")\n        else:\n            response = requests.get(f\"{self.base_url}/api/download\", params={\n                \"author\": author,\n                \"name\": name,\n                \"version\": version\n            })\n            response.raise_for_status()\n            agent_data = response.json()\n\n            self._save_agent_to_cache(agent_data, cache_path)\n            print(f\"Agent {author}/{name} (v{version}) downloaded successfully.\")\n\n        if not self.check_reqs_installed(cache_path):\n            self.install_agent_reqs(cache_path)\n\n        return str(cache_path)\n\n    def _get_agent_files(self, folder_path: str) -> List[Dict[str, str]]:\n        files = []\n        for root, _, filenames in os.walk(folder_path):\n            for filename in filenames:\n                file_path = os.path.join(root, filename)\n                relative_path = os.path.relpath(file_path, folder_path)\n                with open(file_path, \"rb\") as f:\n                    content = base64.b64encode(f.read()).decode('utf-8')\n                files.append({\n                    \"path\": relative_path,\n                    \"content\": content\n                })\n        return files\n\n    def _get_agent_metadata(self, folder_path: str) -> Dict[str, str]:\n        config_path = os.path.join(folder_path, \"config.json\")\n        if os.path.exists(config_path):\n            with open(config_path, \"r\") as f:\n                return json.load(f)\n        return {}\n\n    def _get_cache_path(self, author: str, name: str, version: str) -> Path:\n        return self.cache_dir / author / name / version\n\n    def _save_agent_to_cache(self, agent_data: Dict, cache_path: Path):\n        cache_path.mkdir(parents=True, exist_ok=True)\n        for file_data in agent_data[\"files\"]:\n            file_path = cache_path / file_data[\"path\"]\n            file_path.parent.mkdir(parents=True, exist_ok=True)\n            with open(file_path, \"wb\") as f:\n                f.write(base64.b64decode(file_data[\"content\"]))\n\n    def list_available_agents(self) -> List[Dict[str, str]]:\n        response = requests.get(f\"{self.base_url}/api/list_agents\")\n        response.raise_for_status()\n        return response.json()\n\n    def check_agent_updates(self, author: str, name: str, current_version: str) -> bool:\n        response = requests.get(f\"{self.base_url}/api/check_updates\", params={\n            \"author\": author,\n            \"name\": name,\n            \"current_version\": current_version\n        })\n        response.raise_for_status()\n        return response.json()[\"update_available\"]\n\n    def check_reqs_installed(self, agent_path: Path) -> bool:\n        reqs_path = agent_path / \"meta_requirements.txt\"\n        if not reqs_path.exists():\n            return True  # No requirements file, consider it as installed\n\n        try:\n            result = subprocess.run(['conda', 'list'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n        except Exception:\n            result = subprocess.run(['pip', 'list', '--format=freeze'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n\n        with open(reqs_path, \"r\") as f:\n            reqs = [line.strip().split(\"==\")[0] for line in f if line.strip() and not line.startswith(\"#\")]\n\n        output = result.stdout.decode('utf-8')\n        installed_packages = [line.split()[0] for line in output.splitlines() if line]\n\n        return all(req in installed_packages for req in reqs)\n\n    def install_agent_reqs(self, agent_path: Path):\n        reqs_path = agent_path / \"meta_requirements.txt\"\n        if not reqs_path.exists():\n            print(\"No meta_requirements.txt found. Skipping dependency installation.\")\n            return\n\n        log_path = agent_path / \"deplogs.txt\"\n\n        print(f\"Installing dependencies for agent. Writing to {log_path}\")\n\n        with open(log_path, \"a\") as f:\n            subprocess.check_call([\n                sys.executable,\n                \"-m\",\n                \"pip\",\n                \"install\",\n                \"-r\",\n                str(reqs_path)\n            ], stdout=f, stderr=f)\n\nif __name__ == '__main__':\n    manager = AgentManager('http://localhost:3000')\n    # manager.upload_agent('Balaji R', 'Cool Agent', '0.0.1', '/Users/rama2r/AIOS/pyopenagi/agents/example/academic_agent')\n    # manager.upload_agent(None, None, None, '/Users/rama2r/AIOS/pyopenagi/agents/example/academic_agent')\n    downloaded_path = manager.download_agent('example', 'academic_agent', '0.0.1')\n    # print(f\"Agent downloaded to: {downloaded_path}\")"
  },
  {
    "path": "pyopenagi/queues/README.md",
    "content": "# pyopenagi/queues\n\nThis contains implementations for queries to be passed to the LLM in a queue format so that we can have some waiting while one request is completing. \n"
  },
  {
    "path": "pyopenagi/queues/base_queue.py",
    "content": "import queue\n\nclass BaseQueue:\n\n    _queue = queue.Queue()\n\n    @classmethod\n    def add_message(cls, message):\n        cls._queue.put(message)\n\n    @classmethod\n    def get_message(cls):\n        return cls._queue.get(block=True, timeout=1)\n\n    @classmethod\n    def is_empty(cls):\n        return cls._queue.empty()\n"
  },
  {
    "path": "pyopenagi/queues/llm_request_queue.py",
    "content": "from .base_queue import BaseQueue\n\nclass LLMRequestQueue(BaseQueue):\n    pass\n"
  },
  {
    "path": "pyopenagi/tools/README.md",
    "content": "# pyopenagi/tools\n\nThis is where all the tools are located. Each tool requires you to subclass the base tool and add the features required.\n"
  },
  {
    "path": "pyopenagi/tools/__init__.py",
    "content": ""
  },
  {
    "path": "pyopenagi/tools/arxiv/arxiv.py",
    "content": "import re\n\nfrom ..base import BaseTool\n\nimport arxiv\n\nfrom typing import Optional\n\nclass Arxiv(BaseTool):\n    \"\"\"Arxiv Tool, refactored from Langchain.\n\n    To use, you should have the ``arxiv`` python package installed.\n    https://lukasschwab.me/arxiv.py/index.html\n    This wrapper will use the Arxiv API to conduct searches and\n    fetch document summaries. By default, it will return the document summaries\n    of the top-k results.\n    If the query is in the form of arxiv identifier\n    (see https://info.arxiv.org/help/find/index.html), it will return the paper\n    corresponding to the arxiv identifier.\n    It limits the Document content by doc_content_chars_max.\n    Set doc_content_chars_max=None if you don't want to limit the content size.\n\n    Attributes:\n        top_k_results: number of the top-scored document used for the arxiv tool\n        ARXIV_MAX_QUERY_LENGTH: the cut limit on the query used for the arxiv tool.\n        load_max_docs: a limit to the number of loaded documents\n        load_all_available_meta:\n            if True: the `metadata` of the loaded Documents contains all available\n            meta info (see https://lukasschwab.me/arxiv.py/index.html#Result),\n            if False: the `metadata` contains only the published date, title,\n            authors and summary.\n        doc_content_chars_max: an optional cut limit for the length of a document's\n            content\n    \"\"\"\n\n    def __init__(self):\n        super().__init__()\n        self.top_k_results: int = 3\n        self.ARXIV_MAX_QUERY_LENGTH: int = 300\n        self.load_max_docs: int = 100\n        self.load_all_available_meta: bool = False\n        self.doc_content_chars_max: Optional[int] = 4000\n        self.build_client()\n\n    def is_arxiv_identifier(self, query: str) -> bool:\n        \"\"\"Check if a query is an arxiv identifier.\"\"\"\n        arxiv_identifier_pattern = r\"\\d{2}(0[1-9]|1[0-2])\\.\\d{4,5}(v\\d+|)|\\d{7}.*\"\n        for query_item in query[: self.ARXIV_MAX_QUERY_LENGTH].split():\n            match_result = re.match(arxiv_identifier_pattern, query_item)\n            if not match_result:\n                return False\n            assert match_result is not None\n            if not match_result.group(0) == query_item:\n                return False\n        return True\n\n    def build_client(self):\n        \"\"\"Validate that the python package exists in environment.\"\"\"\n        self.arxiv_search = arxiv.Search\n        self.arxiv_exceptions = arxiv.ArxivError\n\n    def run(self, params) -> str:\n        \"\"\"\n        Performs an arxiv search and A single string\n        with the publish date, title, authors, and summary\n        for each article separated by two newlines.\n\n        If an error occurs or no documents found, error text\n        is returned instead. Wrapper for\n        https://lukasschwab.me/arxiv.py/index.html#Search\n\n        Args:\n            query: a plaintext search query\n        \"\"\"  # noqa: E501\n        query = params[\"query\"]\n        try:\n            if self.is_arxiv_identifier(query):\n                results = self.arxiv_search(\n                    id_list=query.split(),\n                    max_results=self.top_k_results,\n                ).results()\n            else:\n                results = self.arxiv_search(  # type: ignore\n                    query[: self.ARXIV_MAX_QUERY_LENGTH], max_results=self.top_k_results\n                ).results()\n        except self.arxiv_exceptions as ex:\n            return f\"Arxiv exception: {ex}\"\n        docs = [\n            f\"Published: {result.updated.date()}\\n\"\n            f\"Title: {result.title}\\n\"\n            f\"Authors: {', '.join(a.name for a in result.authors)}\\n\"\n            f\"Summary: {result.summary}\"\n            for result in results\n        ]\n        if docs:\n            return \"\\n\\n\".join(docs)[: self.doc_content_chars_max]\n        else:\n            return \"No good Arxiv Result was found\"\n\n    def get_tool_call_format(self):\n        tool_call_format = {\n            \"type\": \"function\",\n            \"function\": {\n                \"name\": \"arxiv\",\n                \"description\": \"Query articles or topics in arxiv\",\n                \"parameters\": {\n                    \"type\": \"object\",\n                    \"properties\": {\n                        \"query\": {\n                            \"type\": \"string\",\n                            \"description\": \"Input query that describes what to search in arxiv\"\n                        }\n                    },\n                    \"required\": [\n                        \"query\"\n                    ]\n                }\n            }\n        }\n        return tool_call_format\n"
  },
  {
    "path": "pyopenagi/tools/base.py",
    "content": "class BaseTool:\n    \"\"\"Base class for calling tools\n    \"\"\"\n    def __init__(self) -> None:\n        pass\n\n    def run(self, params) -> None:\n        pass\n\n    def get_tool_call_format(self) -> dict:\n        \"\"\"Get tool calling format following the function calling from OpenAI: https://platform.openai.com/docs/guides/function-calling\n        \"\"\"\n        pass\n\nclass BaseRapidAPITool(BaseTool):\n    \"\"\"Base class for calling tools from rapidapi hub: https://rapidapi.com/hub\n    \"\"\"\n    def __init__(self):\n        super().__init__()\n        self.url: str = None\n        self.host_name: str = None\n        self.api_key: str = None\n\n    def run(self, params: dict):\n        pass\n\n    def get_tool_call_format(self) -> dict:\n        pass\n\n\nclass BaseHuggingfaceTool(BaseTool):\n    \"\"\"Base class for calling models from huggingface\n\n    \"\"\"\n    def __init__(self):\n        super().__init__()\n        self.url: str = None\n        self.host_name: str = None\n        self.api_key: str = None\n\n    def run(self, params: dict):\n        pass\n\n    def get_tool_call_format(self) -> dict:\n        pass\n"
  },
  {
    "path": "pyopenagi/tools/bing/bing_search.py",
    "content": "import requests\n\nfrom ..base import BaseTool\n\nfrom typing import List\n# from pydantic import root_validator\n\nfrom pyopenagi.utils.utils import get_from_env\n\nclass BingSearch(BaseTool):\n    \"\"\"Bing Search Tool, refactored from langchain.\n    In order to set this up, follow instructions at:\n    https://levelup.gitconnected.com/api-tutorial-how-to-use-bing-web-search-api-in-python-4165d5592a7e\n    \"\"\"\n    def __init__(self):\n        super().__init__()\n        self.url = \"https://api.bing.microsoft.com/v7.0/search\" # temporarily\n        self.bing_subscription_key = get_from_env(\"BING_SUBSCRIPTION_KEY\")\n        self.k: int = 10 # topk searched results\n        # search_kwargs: dict\n\n    def _bing_search_results(self, search_term: str, count: int) -> List[dict]:\n        headers = {\"Ocp-Apim-Subscription-Key\": self.bing_subscription_key}\n        params = {\n            \"q\": search_term,\n            \"count\": count,\n            \"textDecorations\": True,\n            \"textFormat\": \"HTML\",\n            # **self.search_kwargs,\n        }\n        response = requests.get(\n            self.bing_search_url,\n            headers=headers,\n            params=params,  # type: ignore\n        )\n        response.raise_for_status()\n        search_results = response.json()\n        if \"webPages\" in search_results:\n            return search_results[\"webPages\"][\"value\"]\n        return []\n\n    def run(self, query: str) -> str:\n        \"\"\"Run query through BingSearch and parse result.\"\"\"\n        response = self._bing_search_results(query, count=self.k)\n        result = self.parse_result(response)\n        return result\n\n    def parse_result(self, response):\n        snippets = []\n        if len(response) == 0:\n            return \"No good Bing Search Result was found\"\n        for result in response:\n            snippets.append(result[\"snippet\"])\n\n        return \" \".join(snippets)\n"
  },
  {
    "path": "pyopenagi/tools/currency_converter/currency_converter.py",
    "content": "from ..base import BaseRapidAPITool\n\nfrom pyopenagi.utils.utils import get_from_env\n\nimport requests\n\nclass CurrencyConverter(BaseRapidAPITool):\n    def __init__(self):\n        super().__init__()\n        self.url = \"https://currency-converter5.p.rapidapi.com/currency/convert\"\n        self.host_name = \"currency-converter5.p.rapidapi.com\"\n        self.api_key = get_from_env(\"RAPID_API_KEY\")\n\n    def run(self, params: dict):\n        headers = {\n            \"X-RapidAPI-Key\": self.api_key,\n            \"X-RapidAPI-Host\": self.host_name\n        }\n        try:\n            self.query_string = {\n                \"from\": params[\"from\"],\n                \"to\": params[\"to\"],\n                \"amount\": params[\"amount\"] if \"amount\" in params else \"1.0\"\n            }\n        except ValueError:\n            raise KeyError(\n                \"The keys in params do not match the excepted keys in params for currency converter api. \"\n                \"Please make sure it contains two keys: 'from' and 'to'\"\n            )\n\n        response = requests.get(self.url, headers=headers, params=self.query_string).json()\n\n        result = self.parse_result(response)\n        return result\n\n    def parse_result(self, response) -> str:\n        results = []\n        amount = str(response[\"amount\"])\n        base = response[\"base_currency_name\"]\n        rates = response[\"rates\"]\n\n        for key, value in rates.items():\n            converted = value[\"currency_name\"]\n            converted_rate = value[\"rate\"]\n            converted_amount = value[\"rate_for_amount\"]\n            results.append(\"Currency from \" + base + \" to \" + converted + \"is \" + converted_rate + \".\", )\n            results.append(amount + \" \" + base + \"can be converted to \" + converted_amount + \" \" + converted + \".\")\n\n        return \" \".join(results)\n\n    def get_tool_call_format(self):\n        tool_call_format = {\n            \"type\": \"function\",\n            \"function\": {\n                \"name\": \"currency_converter\",\n                \"description\": \"Provides currency exchange rates convert base currency to desired currency with the given amount\",\n                \"parameters\": {\n                    \"type\": \"object\",\n                    \"properties\": {\n                        \"from\": {\n                            \"type\": \"string\",\n                            \"description\": \"Base currency code, e.g., AUD, CAD, EUR, GBP...\"\n                        },\n                        \"to\": {\n                            \"type\": \"string\",\n                            \"description\": \"Desired currency code, e.g., AUD, CAD, EUR, GBP...\"\n                        },\n                        \"amount\": {\n                            \"type\": \"string\",\n                            \"default\": \"1.0\",\n                            \"description\": \"The amount to be converted\"\n                        }\n                    },\n                    \"required\": [\n                        \"from\",\n                        \"to\"\n                    ]\n                }\n            }\n        }\n        return tool_call_format\n"
  },
  {
    "path": "pyopenagi/tools/google/google_places.py",
    "content": "import logging\nfrom typing import Any, Dict, Optional\n\nfrom ..base import BaseTool\n\nfrom pyopenagi.utils.utils import get_from_env\n\n\nclass GooglePlaces(BaseTool):\n    \"\"\"Google Places API, refactored from langchain.\n\n    To use, you should have the ``googlemaps`` python package installed,\n     **an API key for the google maps platform**,\n     and the environment variable ''GPLACES_API_KEY''\n     set with your API key , or pass 'gplaces_api_key'\n     as a named parameter to the constructor.\n\n    By default, this will return the all the results on the input query.\n     You can use the top_k_results argument to limit the number of results.\n\n    Example:\n        .. code-block:: python\n\n\n            from langchain_community.utilities import GooglePlacesAPIWrapper\n            gplaceapi = GooglePlacesAPIWrapper()\n    \"\"\"\n    def __init__(self):\n        super().__init__()\n        self.gplaces_api_key = get_from_env(\"GPLACES_API_KEY\")\n        self.google_map_client: Any  #: :meta private:\n        self.top_k_results: Optional[int] = None\n\n    def build_client(self):\n        \"\"\"Validate that api key is in your environment variable.\"\"\"\n        try:\n            import googlemaps\n\n            client = googlemaps.Client(self.gplaces_api_key)\n        except ImportError:\n            raise ImportError(\n                \"Could not import googlemaps python package. \"\n                \"Please install it with `pip install googlemaps`.\"\n            )\n        return client\n\n    def run(self, query: str) -> str:\n        \"\"\"Run Places search and get k number of places that exists that match.\"\"\"\n        search_results = self.google_map_client.places(query)[\"results\"]\n        num_to_return = len(search_results)\n\n        places = []\n\n        if num_to_return == 0:\n            return \"Google Places did not find any places that match the description\"\n\n        num_to_return = (\n            num_to_return\n            if self.top_k_results is None\n            else min(num_to_return, self.top_k_results)\n        )\n\n        for i in range(num_to_return):\n            result = search_results[i]\n            details = self.fetch_place_details(result[\"place_id\"])\n\n            if details is not None:\n                places.append(details)\n\n        return \"\\n\".join([f\"{i+1}. {item}\" for i, item in enumerate(places)])\n\n    def fetch_place_details(self, place_id: str) -> Optional[str]:\n        try:\n            place_details = self.google_map_client.place(place_id)\n            place_details[\"place_id\"] = place_id\n            formatted_details = self.format_place_details(place_details)\n            return formatted_details\n        except Exception as e:\n            logging.error(f\"An Error occurred while fetching place details: {e}\")\n            return None\n\n    def format_place_details(self, place_details: Dict[str, Any]) -> Optional[str]:\n        try:\n            name = place_details.get(\"result\", {}).get(\"name\", \"Unknown\")\n            address = place_details.get(\"result\", {}).get(\n                \"formatted_address\", \"Unknown\"\n            )\n            phone_number = place_details.get(\"result\", {}).get(\n                \"formatted_phone_number\", \"Unknown\"\n            )\n            website = place_details.get(\"result\", {}).get(\"website\", \"Unknown\")\n            place_id = place_details.get(\"result\", {}).get(\"place_id\", \"Unknown\")\n\n            formatted_details = (\n                f\"{name}\\nAddress: {address}\\n\"\n                f\"Google place ID: {place_id}\\n\"\n                f\"Phone: {phone_number}\\nWebsite: {website}\\n\\n\"\n            )\n            return formatted_details\n        except Exception as e:\n            logging.error(f\"An error occurred while formatting place details: {e}\")\n            return None\n"
  },
  {
    "path": "pyopenagi/tools/google/google_search.py",
    "content": "from ..base import BaseTool\n\nfrom pyopenagi.utils.utils import get_from_env\n\nfrom typing import List, Any\n\nclass GoogleSearch(BaseTool):\n    \"\"\"Google Search Tool, refactored from langchain.\n\n    Adapted from: Instructions adapted from https://stackoverflow.com/questions/\n    37083058/\n    programmatically-searching-google-in-python-using-custom-search\n\n    1. Install google-api-python-client\n    - If you don't already have a Google account, sign up.\n    - If you have never created a Google APIs Console project,\n    read the Managing Projects page and create a project in the Google API Console.\n    - Install the library using pip install google-api-python-client\n\n    2. Enable the Custom Search API\n    - Navigate to the APIs & Services→Dashboard panel in Cloud Console.\n    - Click Enable APIs and Services.\n    - Search for Custom Search API and click on it.\n    - Click Enable.\n    URL for it: https://console.cloud.google.com/apis/library/customsearch.googleapis\n    .com\n\n    3. To create an API key:\n    - Navigate to the APIs & Services → Credentials panel in Cloud Console.\n    - Select Create credentials, then select API key from the drop-down menu.\n    - The API key created dialog box displays your newly created key.\n    - You now have an API_KEY\n\n    Alternatively, you can just generate an API key here:\n    https://developers.google.com/custom-search/docs/paid_element#api_key\n\n    4. Setup Custom Search Engine so you can search the entire web\n    - Create a custom search engine here: https://programmablesearchengine.google.com/.\n    - In `What to search` to search, pick the `Search the entire Web` option.\n    After search engine is created, you can click on it and find `Search engine ID`\n      on the Overview page.\n\n    \"\"\"\n    def __init__(self):\n        super().__init__()\n        self.google_api_key = get_from_env(\"GOOGLE_API_KEY\")\n        self.google_cse_id = get_from_env(\"GOOGLE_CSE_ID\")\n        self.k: int = 10 # topk searched results\n        self.search_engine = self.build_engine()\n        self.siterestrict: bool = False\n\n    def build_engine(self):\n        try:\n            from googleapiclient.discovery import build\n\n        except ImportError:\n            raise ImportError(\n                \"google-api-python-client is not installed. \"\n                \"Please install it with `pip install google-api-python-client\"\n                \">=2.100.0`\"\n            )\n        engine = build(\"customsearch\", \"v1\", developerKey=self.google_api_key)\n        return engine\n\n    def _google_search_results(self, search_term: str, **kwargs: Any) -> List[dict]:\n        cse = self.search_engine.cse()\n        if self.siterestrict:\n            cse = cse.siterestrict() # TODO add siterestrict verification\n        res = cse.list(q=search_term, cx=self.google_cse_id, **kwargs).execute()\n        return res.get(\"items\", [])\n\n\n    def run(self, params: dict) -> str:\n        \"\"\"Run query through GoogleSearch and parse result.\"\"\"\n        query = params[\"query\"]\n        # print(query)\n        response = self._google_search_results(query, num=self.k)\n        # print(response)\n        result = self.parse_result(response)\n        print(result)\n        return result\n\n    def parse_result(self, response):\n        snippets = []\n        if len(response) == 0:\n            return \"No good Google Search Result was found\"\n        for result in response:\n            if \"snippet\" in result:\n                snippets.append(result[\"snippet\"])\n\n        return \" \".join(snippets)\n\n    def get_tool_call_format(self):\n        tool_call_format = {\n            \"type\": \"function\",\n            \"function\": {\n                \"name\": \"google_search\",\n                \"description\": \"search information using google search api\",\n                \"parameters\": {\n                    \"type\": \"object\",\n                    \"properties\": {\n                        \"query\": {\n                            \"type\": \"string\",\n                            \"description\": \"prompt description of the image to be generated\"\n                        }\n                    },\n                    \"required\": [\n                        \"query\"\n                    ]\n                }\n            }\n        }\n        return tool_call_format\n"
  },
  {
    "path": "pyopenagi/tools/imdb/top_movie.py",
    "content": "from ..base import BaseRapidAPITool\n\nfrom typing import Any, Dict, List, Optional\n\n# from pydantic import root_validator\n\nfrom pyopenagi.utils.utils import get_from_env\n\nimport requests\n\nclass TopMovieAPI(BaseRapidAPITool):\n    def __init__(self):\n        super().__init__()\n        self.url = \"https://imdb-top-100-movies.p.rapidapi.com/\"\n        self.host_name = \"imdb-top-100-movies.p.rapidapi.com\"\n\n        self.api_key = get_from_env(\"RAPID_API_KEY\")\n\n    def run(self, params):\n        start = int(params[\"start\"]) if \"start\" in params else 1\n        end = int(params[\"end\"])\n        headers = {\n            \"X-RapidAPI-Key\": self.api_key,\n            \"X-RapidAPI-Host\": self.host_name\n        }\n        response = requests.get(self.url, headers=headers).json()\n        result = self.parse_result(response, start, end)\n        return result\n\n\n    def parse_result(self, response, start, end) -> str:\n        result = []\n        # print(response)\n        for i in range(start, end):\n            item = response[i]\n            result.append(f'{item[\"title\"]}, {item[\"genre\"]}, {item[\"rating\"]}, published in {item[\"year\"]}')\n\n        return f\"Top {start}-{end} series ranked by IMDB are: \" + \";\".join(result)\n\n    def get_tool_call_format(self):\n        tool_call_format = {\n            \"type\": \"function\",\n            \"function\": {\n                \"name\": \"top_movies\",\n                \"description\": \"Query the latest top start-to-end movies ranked by Imdb\",\n                \"parameters\": {\n                    \"type\": \"object\",\n                    \"properties\": {\n                        \"start\": {\n                            \"type\": \"string\",\n                            \"description\": \"start of the rank range of the Imdb movies\",\n                            \"default\": \"1\"\n                        },\n                        \"end\": {\n                            \"type\": \"string\",\n                            \"description\": \"end of the rank range of the Imdb movies\"\n                        }\n                    },\n                    \"required\": [\n                        \"end\"\n                    ]\n                }\n            }\n        }\n        return tool_call_format\n"
  },
  {
    "path": "pyopenagi/tools/imdb/top_movies.py",
    "content": "from ..base import BaseRapidAPITool\n\n# from pydantic import root_validator\n\nfrom pyopenagi.utils.utils import get_from_env\n\nimport requests\n\nclass TopMovies(BaseRapidAPITool):\n    def __init__(self):\n        super().__init__()\n        self.url = \"https://imdb-top-100-movies.p.rapidapi.com/\"\n        self.host_name = \"imdb-top-100-movies.p.rapidapi.com\"\n\n        self.api_key = get_from_env(\"RAPID_API_KEY\")\n\n    def run(self, params):\n        start = int(params[\"start\"]) if \"start\" in params else 1\n        end = int(params[\"end\"])\n        headers = {\n            \"X-RapidAPI-Key\": self.api_key,\n            \"X-RapidAPI-Host\": self.host_name\n        }\n        response = requests.get(self.url, headers=headers).json()\n        result = self.parse_result(response, start, end)\n        return result\n\n\n    def parse_result(self, response, start, end) -> str:\n        result = []\n        # print(response)\n        for i in range(start, end):\n            item = response[i]\n            result.append(f'{item[\"title\"]}, {item[\"genre\"]}, {item[\"rating\"]}, published in {item[\"year\"]}')\n\n        return f\"Top {start}-{end} series ranked by IMDB are: \" + \";\".join(result)\n\n    def get_tool_call_format(self):\n        tool_call_format = {\n            \"type\": \"function\",\n            \"function\": {\n                \"name\": \"top_movies\",\n                \"description\": \"Query the latest top start-to-end movies ranked by Imdb\",\n                \"parameters\": {\n                    \"type\": \"object\",\n                    \"properties\": {\n                        \"start\": {\n                            \"type\": \"string\",\n                            \"description\": \"start of the rank range of the Imdb movies\",\n                            \"default\": \"1\"\n                        },\n                        \"end\": {\n                            \"type\": \"string\",\n                            \"description\": \"end of the rank range of the Imdb movies\"\n                        }\n                    },\n                    \"required\": [\n                        \"end\"\n                    ]\n                }\n            }\n        }\n        return tool_call_format\n"
  },
  {
    "path": "pyopenagi/tools/imdb/top_series.py",
    "content": "from ..base import BaseRapidAPITool\n\nfrom pyopenagi.utils.utils import get_from_env\n\nimport requests\n\nclass TopSeries(BaseRapidAPITool):\n    def __init__(self):\n        super().__init__()\n        self.url = \"https://imdb-top-100-movies.p.rapidapi.com/series/\"\n        self.host_name = \"imdb-top-100-movies.p.rapidapi.com\"\n\n        self.api_key = get_from_env(\"RAPID_API_KEY\")\n\n    def run(self, params):\n        start = int(params[\"start\"]) if \"start\" in params else 1\n        end = int(params[\"end\"])\n        headers = {\n            \"X-RapidAPI-Key\": self.api_key,\n            \"X-RapidAPI-Host\": self.host_name\n        }\n        response = requests.get(self.url, headers=headers).json()\n        result = self.parse_result(response, start, end)\n        return result\n\n\n    def parse_result(self, response, start, end) -> str:\n        result = []\n        for i in range(start, end):\n            item = response[i]\n            result.append(f'{item[\"title\"]}, {item[\"genre\"]}, {item[\"rating\"]}, published in {item[\"year\"]}')\n\n        return f\"Top {start}-{end} series ranked by IMDB are: \" + \";\".join(result)\n\n    def get_tool_call_format(self):\n        tool_call_format = {\n            \"type\": \"function\",\n            \"function\": {\n                \"name\": \"imdb_top_series\",\n                \"description\": \"Query the latest top start-to-end series ranked by Imdb\",\n                \"parameters\": {\n                    \"type\": \"object\",\n                    \"properties\": {\n                        \"start\": {\n                            \"type\": \"string\",\n                            \"description\": \"start of the rank range of the Imdb series\",\n                            \"default\": \"1\"\n                        },\n                        \"end\": {\n                            \"type\": \"string\",\n                            \"description\": \"end of the rank range of the Imdb series\"\n                        }\n                    },\n                    \"required\": [\n                        \"end\"\n                    ]\n                }\n            }\n        }\n        return tool_call_format\n"
  },
  {
    "path": "pyopenagi/tools/impira/doc_question_answering.py",
    "content": "import requests\n\nfrom ...utils.utils import get_from_env\n\nfrom ..base import BaseHuggingfaceTool\n\nimport base64\n\nclass DocQuestionAnswering(BaseHuggingfaceTool):\n    def __init__(self):\n        super().__init__()\n\n    def run(self, params):\n\n        API_URL = \"https://api-inference.huggingface.co/models/impira/layoutlm-document-qa\"\n        headers = {\"Authorization\": \"Bearer \" + get_from_env(\"HF_AUTH_TOKENS\")}\n\n        question = params[\"question\"]\n\n        path = params[\"path\"]\n\n        with open(path, \"rb\") as f:\n            img = f.read()\n\n        payload = {\n             \"input\": {\n                  \"image\": base64.b64encode(img).decode(\"utf-8\")\n             },\n             \"question\": question\n        }\n        response = requests.post(API_URL, headers=headers, json=payload)\n        return response.json()\n\n\n    def get_tool_call_format(self):\n        tool_call_format = {\n            \"type\": \"function\",\n            \"function\": {\n                \"name\": \"doc_question_answering\",\n                \"description\": \"answer the question based on the given document\",\n                \"parameters\": {\n                    \"type\": \"object\",\n                    \"properties\": {\n                        \"question\": {\n                            \"type\": \"string\",\n                            \"description\": \"question that needs to be answered\"\n                        },\n                        \"path\": {\n                             \"type\": \"string\",\n                             \"description\": \"path of the document\"\n                        }\n                    },\n                    \"required\": [\n                        \"question\",\n                        \"path\"\n                    ]\n                }\n            }\n        }\n        return tool_call_format\n"
  },
  {
    "path": "pyopenagi/tools/meteosource_weather/find_place.py",
    "content": "from ..base import BaseRapidAPITool\n\n# from pydantic import root_validator\n\nfrom pyopenagi.utils.utils import get_from_env\n\nimport requests\n\nclass SongAutocompleteAPI(BaseRapidAPITool):\n    def __init__(self):\n        super().__init__()\n        self.url = \"https://ai-weather-by-meteosource.p.rapidapi.com/find_places\"\n        self.host_name = \"ai-weather-by-meteosource.p.rapidapi.com\"\n\n        self.api_key = get_from_env(\"RAPID_API_KEY\")\n\n    def run(self, params):\n        headers = {\n            \"X-RapidAPI-Key\": self.api_key,\n            \"X-RapidAPI-Host\": self.host_name\n        }\n        try:\n            self.query_string = {\n                \"text\": params[\"text\"],\n                \"language\": params[\"language\"]\n            }\n        except ValueError:\n            raise KeyError(\n                \"The keys in params do not match the excepted keys in params for weather find place api. \"\n                \"Please make sure it contains two keys: 'text' and 'language'\"\n            )\n        response = requests.get(self.url, headers=headers, params=self.query_string).json()\n\n        result = self.parse_result(response)\n        return result\n\n\n    def parse_result(self, response) -> str:\n        location = [\n            response[\"radm_area1\"],\n            response[\"adm_area2\"],\n            response[\"country\"],\n            response[\"lat\"],\n            response[\"lon\"]\n        ]\n        return f\"Found place of {response[\"name\"]}: \" + \",\".join(location)\n"
  },
  {
    "path": "pyopenagi/tools/moonphase/moon_phase_search.py",
    "content": "from ..base import BaseRapidAPITool\n\nfrom pyopenagi.utils.utils import get_from_env\n\nimport requests\n\nclass MoonPhaseSearch(BaseRapidAPITool):\n    def __init__(self):\n        super().__init__()\n        self.url = \"https://moon-phase.p.rapidapi.com/basic\"\n        self.host_name = \"moon-phase.p.rapidapi.com\"\n        self.api_key = get_from_env(\"RAPID_API_KEY\")\n\n    def run(self):\n        headers = {\n            \"X-RapidAPI-Key\": self.api_key,\n            \"X-RapidAPI-Host\": self.host_name\n        }\n        response = requests.get(self.url, headers=headers)\n\n        result = self.parse_result(response)\n        return result\n\n    def parse_result(self, response) -> str:\n        return f'Current moon phase is {response[\"phase_name\"]}. It has {response[\"days_until_next_full_moon\"]} until next full moon. It has {response[\"days_until_next_new_moon\"]} until the next new moon.'\n"
  },
  {
    "path": "pyopenagi/tools/openai/speech_to_text.py",
    "content": "import requests\n\nimport soundfile as sf\n\nfrom ...utils.utils import get_from_env\n\nfrom ..base import BaseHuggingfaceTool\n\nclass SpeechToText(BaseHuggingfaceTool):\n    def __init__(self):\n        super().__init__()\n\n    def run(self, params):\n        API_URL = \"https://api-inference.huggingface.co/models/openai/whisper-large-v3\"\n        headers = {\"Authorization\": \"Bearer \" + get_from_env(\"HF_AUTH_TOKENS\")}\n\n        path = params[\"path\"]\n\n        data = sf.read(path)\n        response = requests.post(API_URL, headers=headers, data=data)\n        text = response.content\n        return text\n\n    def get_tool_call_format(self):\n        tool_call_format = {\n            \"type\": \"function\",\n            \"function\": {\n                \"name\": \"speech_to_text\",\n                \"description\": \"translate the voice into texts\",\n                \"parameters\": {\n                    \"type\": \"object\",\n                    \"properties\": {\n                        \"path\": {\n                             \"type\": \"string\",\n                             \"description\": \"path of the saved audio\"\n                        }\n                    },\n                    \"required\": [\n                        \"path\"\n                    ]\n                }\n            }\n        }\n        return tool_call_format\n"
  },
  {
    "path": "pyopenagi/tools/shazam/song_auto_complete.py",
    "content": "from ..base import BaseRapidAPITool\n\n# from pydantic import root_validator\n\nfrom pyopenagi.utils.utils import get_from_env\n\nimport requests\n\nclass SongAutoComplete(BaseRapidAPITool):\n    def __init__(self):\n        super().__init__()\n        self.url = \"https://shazam.p.rapidapi.com/auto-complete\"\n        self.host_name = \"shazam.p.rapidapi.com\"\n\n        self.api_key = get_from_env(\"RAPID_API_KEY\")\n\n    def run(self, params):\n        headers = {\n            \"X-RapidAPI-Key\": self.api_key,\n            \"X-RapidAPI-Host\": self.host_name\n        }\n        try:\n            self.query_string = {\n                \"term\": params[\"term\"],\n                \"locale\": params[\"locale\"]\n            }\n        except ValueError:\n            raise KeyError(\n                \"The keys in params do not match the excepted keys in params for currency converter api. \"\n                \"Please make sure it contains two keys: 'term' and 'locale'\"\n            )\n        response = requests.get(self.url, headers=headers, params=self.query_string).json()\n\n        result = self.parse_result(response)\n        return result\n\n\n    def parse_result(self, response) -> str:\n        return \"Completion hints are: \" + \",\".join(response[\"hints\"].values())\n"
  },
  {
    "path": "pyopenagi/tools/stability-ai/sdxl_turbo.py",
    "content": "from diffusers import AutoPipelineForText2Image\nimport torch\n\nfrom ..base import BaseHuggingfaceTool\n\nclass SdxlTurbo(BaseHuggingfaceTool):\n    def __init__(self):\n        super().__init__()\n        self.pipe = AutoPipelineForText2Image.from_pretrained(\"stabilityai/sdxl-turbo\", torch_dtype=torch.float16, variant=\"fp16\")\n\n    def run(self, params):\n        prompt = params[\"prompt\"]\n        self.pipe.to(\"cuda\")\n        image = self.pipe(prompt=prompt, num_inference_steps=1, guidance_scale=0.0).images[0]\n        return image\n\n    def get_tool_call_format(self):\n        tool_call_format = {\n            \"type\": \"function\",\n            \"function\": {\n                \"name\": \"sdxl_turbo\",\n                \"description\": \"generate images with the given texts\",\n                \"parameters\": {\n                    \"type\": \"object\",\n                    \"properties\": {\n                        \"prompt\": {\n                            \"type\": \"string\",\n                            \"description\": \"prompt description of the image to be generated\"\n                        }\n                    },\n                    \"required\": [\n                        \"prompt\"\n                    ]\n                }\n            }\n        }\n        return tool_call_format\n"
  },
  {
    "path": "pyopenagi/tools/stability-ai/text_to_image.py",
    "content": "from ...utils.utils import get_from_env\n\nfrom ..base import BaseHuggingfaceTool\n\nimport requests\n\nclass TextToImage(BaseHuggingfaceTool):\n    def __init__(self):\n        super().__init__()\n\n    def run(self, params):\n\n        API_URL = \"https://api-inference.huggingface.co/models/stabilityai/stable-diffusion-xl-base-1.0\"\n        headers = {\"Authorization\": \"Bearer \" + get_from_env(\"HF_AUTH_TOKENS\")}\n\n        prompt = params[\"prompt\"]\n\n        path = params[\"path\"]\n\n        payload = {\n            \"inputs\": prompt\n        }\n        response = requests.post(API_URL, headers=headers, json=payload)\n\n        image_bytes = response.content\n        # You can access the image with PIL.Image for example\n        import io\n        from PIL import Image\n\n        image = Image.open(io.BytesIO(image_bytes))\n        image.save(path)\n\n        return f\"a generated image saved at {path}\"\n\n    def get_tool_call_format(self):\n        tool_call_format = {\n            \"type\": \"function\",\n            \"function\": {\n                \"name\": \"text_to_image\",\n                \"description\": \"generate images with the given texts\",\n                \"parameters\": {\n                    \"type\": \"object\",\n                    \"properties\": {\n                        \"prompt\": {\n                            \"type\": \"string\",\n                            \"description\": \"prompt description of the image to be generated\"\n                        },\n                        \"path\": {\n                             \"type\": \"string\",\n                             \"description\": \"path to save the generated image\"\n                        }\n                    },\n                    \"required\": [\n                        \"prompt\",\n                        \"path\"\n                    ]\n                }\n            }\n        }\n        return tool_call_format\n"
  },
  {
    "path": "pyopenagi/tools/suno/text_to_speech.py",
    "content": "import requests\n\nfrom ...utils.utils import get_from_env\n\nfrom ..base import BaseHuggingfaceTool\n\nclass TextToSpeech(BaseHuggingfaceTool):\n    def __init__(self):\n        super().__init__()\n\n    def run(self, params):\n        API_URL = \"https://api-inference.huggingface.co/models/suno/bark\"\n        headers = {\"Authorization\": \"Bearer \" + get_from_env(\"HF_AUTH_TOKENS\")}\n\n        prompt = params[\"prompt\"]\n        path = params[\"path\"]\n\n        payload = {\n             \"prompt\": prompt\n        }\n\n        response = requests.post(API_URL, headers=headers, json=payload)\n\n        with open(path,\"wb\") as f:\n            f.write(response.content)\n\n        return f\"a generated audio saved at {path}\"\n        # pass\n\n    def get_tool_call_format(self):\n        tool_call_format = {\n            \"type\": \"function\",\n            \"function\": {\n                \"name\": \"text_to_speech\",\n                \"description\": \"generate voice based on the text\",\n                \"parameters\": {\n                    \"type\": \"object\",\n                    \"properties\": {\n                        \"prompt\": {\n                             \"type\": \"string\",\n                             \"description\": \"text description\"\n                        },\n                        \"path\": {\n                             \"type\": \"string\",\n                             \"description\": \"path to save the audio\"\n                        }\n                    },\n                    \"required\": [\n                        \"prompt\",\n                        \"path\"\n                    ]\n                }\n            }\n        }\n        return tool_call_format\n"
  },
  {
    "path": "pyopenagi/tools/timbrooks/image_to_image.py",
    "content": "from PIL import Image\nimport torch\nfrom diffusers import StableDiffusionInstructPix2PixPipeline, EulerAncestralDiscreteScheduler\n\nfrom ..base import BaseHuggingfaceTool\n\nclass ImageToImage(BaseHuggingfaceTool):\n    def __init__(self):\n        super().__init__()\n        self.model_id = \"timbrooks/instruct-pix2pix\"\n        self.pipe = StableDiffusionInstructPix2PixPipeline.from_pretrained(self.model_id, torch_dtype=torch.float16, safety_checker=None)\n        self.pipe.to(\"cuda\")\n        self.pipe.scheduler = EulerAncestralDiscreteScheduler.from_config(self.pipe.scheduler.config)\n\n    def run(self, params):\n        path = params[\"old_path\"]\n        image = Image.open(path)\n        prompt = params[\"prompt\"]\n        new_image = self.pipe(prompt, image=image, num_inference_steps=10, image_guidance_scale=1).images\n        new_path = params[\"new_path\"]\n        new_image.save(path)\n        return f\"a new image saved at {new_path}\"\n\n    def get_tool_call_format(self):\n        tool_call_format = {\n            \"type\": \"function\",\n            \"function\": {\n                \"name\": \"text_to_image\",\n                \"description\": \"generate images with the given texts\",\n                \"parameters\": {\n                    \"type\": \"object\",\n                    \"properties\": {\n                        \"prompt\": {\n                            \"type\": \"string\",\n                            \"description\": \"prompt description of the image to be generated\"\n                        },\n                        \"old_path\": {\n                            \"type\": \"string\",\n                            \"description\": \"path to load the old image\"\n                        },\n                        \"new_path\": {\n                            \"type\": \"string\",\n                            \"description\": \"path to save the new generated image\"\n                        }\n                    },\n                    \"required\": [\n                        \"prompt\",\n                        \"old_path\",\n                        \"new_path\"\n                    ]\n                }\n            }\n        }\n        return tool_call_format\n"
  },
  {
    "path": "pyopenagi/tools/transcriber/transcriber.py",
    "content": "from ..base import BaseTool \nfrom time import sleep\n\nclass Transcriber(BaseTool):\n    def __init__(self):\n        \"\"\" big library, not everyone needs it installed \"\"\"\n        try:\n            from RealtimeSTT import AudioToTextRecorder\n        except ImportError:\n            raise ImportError(\n                \"Please install RealtimeSTT: `pip install RealtimeSTT`\"\n            )\n        \n        # this is hardcoded for now\n        self.recorder = AudioToTextRecorder(\n                model=\"tiny.en\",\n        )\n\n    def run(self, params: dict):\n        duration = 5\n        try:\n            duration = int(params[\"duration\"])\n        except ValueError:\n            raise KeyError(\n                \"The keys in params do not match the excepted key in params for transcriber api. \"\n                \"Please make sure it contain the key 'duration'\"\n            )\n\n        self.record.start()\n        sleep(duration)\n        self.recorder.stop()\n        return self.recorder.text() \n\n    def get_tool_call_format(self):\n        tool_call_format = {\n            \"type\": \"function\",\n            \"function\": {\n                \"name\": \"transcriber\",\n                \"description\": \"Transcribes audiio into text\",\n                \"parameters\": {\n                    \"type\": \"object\",\n                    \"properties\": {\n                        \"duration\": {\n                            \"type\": \"string\",\n                            \"description\": \"How long to record audio for in seconds\",\n                        },\n                    },\n                    \"required\": []\n                }\n            }\n        }\n        return tool_call_format\n"
  },
  {
    "path": "pyopenagi/tools/travel_planner/accommodations.py",
    "content": "import pandas as pd\nimport os\nfrom pandas import DataFrame\n\nfrom ..base import BaseTool\n\n\nclass Accommodations(BaseTool):\n    def __init__(self, path=\"../../environments/travelPlanner/accommodations/clean_accommodations_2022.csv\"):\n        current_dir = os.path.dirname(os.path.abspath(__file__))\n        self.path = os.path.join(current_dir, path)\n        self.data = pd.read_csv(self.path).dropna()[\n            ['NAME', 'price', 'room type', 'house_rules', 'minimum nights', 'maximum occupancy', 'review rate number',\n             'city']]\n        print(\"Accommodations loaded.\")\n\n    def load_db(self):\n        self.data = pd.read_csv(self.path).dropna()\n\n    def run(self,\n            city: str,\n            ) -> DataFrame:\n        \"\"\"Search for accommodations by city.\"\"\"\n        results = self.data[self.data[\"city\"] == city]\n        if len(results) == 0:\n            return \"There is no attraction in this city.\"\n\n        return results\n\n    def get_tool_call_format(self):\n        tool_call_format = {\n            \"type\": \"function\",\n            \"function\": {\n                \"name\": \"Accommodations\",\n                \"description\": \"Search for an Accommodations by query\",\n            }\n        }\n        return tool_call_format\n"
  },
  {
    "path": "pyopenagi/tools/travel_planner/attractions.py",
    "content": "import pandas as pd\nimport os\nfrom pandas import DataFrame\n\nfrom ..base import BaseTool\n\n\nclass Attractions(BaseTool):\n    def __init__(self, path=\"../../environments/travelPlanner/attractions/attractions.csv\"):\n        current_dir = os.path.dirname(os.path.abspath(__file__))\n        self.path = os.path.join(current_dir, path)\n        self.data = pd.read_csv(self.path).dropna()[\n            ['Name', 'Latitude', 'Longitude', 'Address', 'Phone', 'Website', \"City\"]]\n        print(\"Attractions loaded.\")\n\n    def load_db(self):\n        self.data = pd.read_csv(self.path)\n\n    def run(self,\n            city: str,\n            ) -> DataFrame:\n        \"\"\"Search for Accommodations by city and date.\"\"\"\n        results = self.data[self.data[\"City\"] == city]\n        # the results should show the index\n        results = results.reset_index(drop=True)\n        if len(results) == 0:\n            return \"There is no attraction in this city.\"\n        return results\n\n    def get_tool_call_format(self):\n        tool_call_format = {\n            \"type\": \"function\",\n            \"function\": {\n                \"name\": \"Attractions\",\n                \"description\": \"Search for Attractions by query\",\n            }\n        }\n        return tool_call_format\n"
  },
  {
    "path": "pyopenagi/tools/travel_planner/cities.py",
    "content": "import os\n\nfrom ..base import BaseTool\n\n\nclass Cities(BaseTool):\n    def __init__(self, path=\"../../environments/travelPlanner/background/citySet_with_states.txt\") -> None:\n        current_dir = os.path.dirname(os.path.abspath(__file__))\n        self.path = os.path.join(current_dir, path)\n        self.load_data()\n        print(\"Cities loaded.\")\n\n    def load_data(self):\n        cityStateMapping = open(self.path, \"r\").read().strip().split(\"\\n\")\n        self.data = {}\n        for unit in cityStateMapping:\n            city, state = unit.split(\"\\t\")\n            if state not in self.data:\n                self.data[state] = [city]\n            else:\n                self.data[state].append(city)\n\n    def run(self, state) -> dict:\n        if state not in self.data:\n            return ValueError(\"Invalid State\")\n        else:\n            return self.data[state]\n\n    def get_tool_call_format(self):\n        tool_call_format = {\n            \"type\": \"function\",\n            \"function\": {\n                \"name\": \"Cities\",\n                \"description\": \"Search for Cities by query\",\n            }\n        }\n        return tool_call_format\n"
  },
  {
    "path": "pyopenagi/tools/travel_planner/flights.py",
    "content": "import pandas as pd\nimport os\nfrom pandas import DataFrame\n\nfrom ..base import BaseTool\n\n\nclass Flights(BaseTool):\n\n    def __init__(self, path=\"../../environments/travelPlanner/flights/clean_Flights_2022.csv\"):\n        current_dir = os.path.dirname(os.path.abspath(__file__))\n        self.path = os.path.join(current_dir, path)\n        self.data = pd.read_csv(self.path).dropna()[\n            ['Flight Number', 'Price', 'DepTime', 'ArrTime', 'ActualElapsedTime', 'FlightDate', 'OriginCityName',\n             'DestCityName', 'Distance']]\n        print(\"Flights loaded.\")\n\n    def load_db(self):\n        self.data = pd.read_csv(self.path).dropna().rename(columns={'Unnamed: 0': 'Flight Number'})\n\n    def run(self,\n            origin: str,\n            destination: str,\n            departure_date: str,\n            ) -> DataFrame:\n        \"\"\"Search for flights by origin, destination, and departure date.\"\"\"\n        results = self.data[self.data[\"OriginCityName\"] == origin]\n        results = results[results[\"DestCityName\"] == destination]\n        results = results[results[\"FlightDate\"] == departure_date]\n\n        if len(results) == 0:\n            return \"There is no flight from {} to {} on {}.\".format(origin, destination, departure_date)\n        return results\n\n    def get_tool_call_format(self):\n        tool_call_format = {\n            \"type\": \"function\",\n            \"function\": {\n                \"name\": \"Flights\",\n                \"description\": \"Search for Flights by query\",\n            }\n        }\n        return tool_call_format\n"
  },
  {
    "path": "pyopenagi/tools/travel_planner/google_distance_matrix.py",
    "content": "import re\nimport os\nimport pandas as pd\nimport numpy as np\n\nfrom ..base import BaseTool\n\n\n\n# This tool refers to the \"DistanceMatrix\" in the paper. Considering this data obtained from Google API,\n# we consistently use this name in the code. Please be assured that this will not influence the experiment results\n# shown in the paper.\n\nclass GoogleDistanceMatrix(BaseTool):\n    def __init__(self, path=\"../../environments/travelPlanner/googleDistanceMatrix/distance.csv\",\n                 subscription_key: str = \"\") -> None:\n        self.gplaces_api_key: str = subscription_key\n        current_dir = os.path.dirname(os.path.abspath(__file__))\n        self.path = os.path.join(current_dir, path)\n        self.data = pd.read_csv(self.path)\n        print(\"GoogleDistanceMatrix loaded.\")\n\n    def run(self, origin, destination, mode='driving'):\n        origin = extract_before_parenthesis(origin)\n        destination = extract_before_parenthesis(destination)\n        info = {\"origin\": origin, \"destination\": destination, \"cost\": None, \"duration\": None, \"distance\": None}\n        response = self.data[(self.data['origin'] == origin) & (self.data['destination'] == destination)]\n        if len(response) > 0:\n            if response['duration'].values[0] is None or response['distance'].values[0] is None or \\\n                    response['duration'].values[0] is np.nan or response['distance'].values[0] is np.nan:\n                return \"No valid information.\"\n            info[\"duration\"] = response['duration'].values[0]\n            info[\"distance\"] = response['distance'].values[0]\n            if 'driving' in mode:\n                info[\"cost\"] = int(eval(info[\"distance\"].replace(\"km\", \"\").replace(\",\", \"\")) * 0.05)\n            elif mode == \"taxi\":\n                info[\"cost\"] = int(eval(info[\"distance\"].replace(\"km\", \"\").replace(\",\", \"\")))\n            if 'day' in info[\"duration\"]:\n                return \"No valid information.\"\n            return f\"{mode}, from {origin} to {destination}, duration: {info['duration']}, distance: {info['distance']}, cost: {info['cost']}\"\n\n        return f\"{mode}, from {origin} to {destination}, no valid information.\"\n\n    def get_tool_call_format(self):\n        tool_call_format = {\n\t\t\t\"type\": \"function\",\n\t\t\t\"function\": {\n\t\t\t\t\"name\": \"GoogleDistanceMatrix\",\n\t\t\t\t\"description\": \"Distance information\",\n\t\t\t}\n\t\t}\n        return tool_call_format\n\n\ndef extract_before_parenthesis(s):\n    match = re.search(r'^(.*?)\\([^)]*\\)', s)\n    return match.group(1) if match else s\n"
  },
  {
    "path": "pyopenagi/tools/travel_planner/notebook.py",
    "content": "from pandas import DataFrame\n\nfrom ..base import BaseTool\n\n\n\nclass Notebook(BaseTool):\n    def __init__(self) -> None:\n        self.data = []\n\n    def run(self, input_data: DataFrame, short_description: str):\n        self.data.append({\"Short Description\": short_description, \"Content\": input_data})\n        return f\"The information has been recorded in Notebook, and its index is {len(self.data) - 1}.\"\n\n    def update(self, input_data: DataFrame, index: int, short_decription: str):\n        self.data[index][\"Content\"] = input_data\n        self.data[index][\"Short Description\"] = short_decription\n\n        return \"The information has been updated in Notebook.\"\n\n    def list(self):\n        results = []\n        for idx, unit in enumerate(self.data):\n            results.append({\"index\": idx, \"Short Description\": unit['Short Description']})\n\n        return results\n\n    def list_all(self):\n        results = []\n        for idx, unit in enumerate(self.data):\n            if type(unit['Content']) is DataFrame:\n                results.append({\"index\": idx, \"Short Description\": unit['Short Description'],\n                                \"Content\": unit['Content'].to_string(index=False)})\n            else:\n                results.append(\n                    {\"index\": idx, \"Short Description\": unit['Short Description'], \"Content\": unit['Content']})\n\n        return results\n\n    def read(self, index):\n        return self.data[index]\n\n    def reset(self):\n        self.data = []\n\n    def get_tool_call_format(self):\n        tool_call_format = {\n\t\t\t\"type\": \"function\",\n\t\t\t\"function\": {\n\t\t\t\t\"name\": \"Notebook\",\n\t\t\t\t\"description\": \"Note information\",\n\t\t\t}\n\t\t}\n        return tool_call_format\n"
  },
  {
    "path": "pyopenagi/tools/travel_planner/planner.py",
    "content": "PLANNER_INSTRUCTION = \"\"\"You are a proficient planner. Based on the provided information and query, please give me a detailed plan, including specifics such as flight numbers (e.g., F0123456), restaurant names, and accommodation names. Note that all the information in your plan should be derived from the provided data. You must adhere to the format given in the example. Additionally, all details should align with commonsense. The symbol '-' indicates that information is unnecessary. For example, in the provided sample, you do not need to plan after returning to the departure city. When you travel to two cities in one day, you should note it in the 'Current City' section as in the example (i.e., from A to B).\n\n***** Example *****\nQuery: Could you create a travel plan for 7 people from Ithaca to Charlotte spanning 3 days, from March 8th to March 14th, 2022, with a budget of $30,200?\nTravel Plan:\nDay 1:\nCurrent City: from Ithaca to Charlotte\nTransportation: Flight Number: F3633413, from Ithaca to Charlotte, Departure Time: 05:38, Arrival Time: 07:46\nBreakfast: Nagaland's Kitchen, Charlotte\nAttraction: The Charlotte Museum of History, Charlotte\nLunch: Cafe Maple Street, Charlotte\nDinner: Bombay Vada Pav, Charlotte\nAccommodation: Affordable Spacious Refurbished Room in Bushwick!, Charlotte\n\nDay 2:\nCurrent City: Charlotte\nTransportation: -\nBreakfast: Olive Tree Cafe, Charlotte\nAttraction: The Mint Museum, Charlotte;Romare Bearden Park, Charlotte.\nLunch: Birbal Ji Dhaba, Charlotte\nDinner: Pind Balluchi, Charlotte\nAccommodation: Affordable Spacious Refurbished Room in Bushwick!, Charlotte\n\nDay 3:\nCurrent City: from Charlotte to Ithaca\nTransportation: Flight Number: F3786167, from Charlotte to Ithaca, Departure Time: 21:42, Arrival Time: 23:26\nBreakfast: Subway, Charlotte\nAttraction: Books Monument, Charlotte.\nLunch: Olive Tree Cafe, Charlotte\nDinner: Kylin Skybar, Charlotte\nAccommodation: -\n\n***** Example Ends *****\n\nGiven information: {text}\nQuery: {query}\nTravel Plan:\"\"\"\n"
  },
  {
    "path": "pyopenagi/tools/travel_planner/restaurants.py",
    "content": "import pandas as pd\nimport os\nfrom pandas import DataFrame\n\nfrom ..base import BaseTool\n\n\nclass Restaurants(BaseTool):\n    def __init__(self, path=\"../../environments/travelPlanner/restaurants/clean_restaurant_2022.csv\"):\n        super().__init__()\n        current_dir = os.path.dirname(os.path.abspath(__file__))\n        self.path = os.path.join(current_dir, path)\n        self.data = pd.read_csv(self.path).dropna()[['Name', 'Average Cost', 'Cuisines', 'Aggregate Rating', 'City']]\n        print(\"Restaurants loaded.\")\n\n    def load_db(self):\n        self.data = pd.read_csv(self.path).dropna()\n\n    def run(self,\n            city: str,\n            ) -> DataFrame:\n        \"\"\"Search for restaurant .\"\"\"\n        results = self.data[self.data[\"City\"] == city]\n\n        if len(results) == 0:\n            return \"There is no restaurant in this city.\"\n        return results\n\n    def get_tool_call_format(self):\n        tool_call_format = {\n            \"type\": \"function\",\n            \"function\": {\n                \"name\": \"Restaurants\",\n                \"description\": \"Search for Restaurants by query\",\n            }\n        }\n        return tool_call_format\n"
  },
  {
    "path": "pyopenagi/tools/trip_advisor/airport_search.py",
    "content": "from ..base import BaseRapidAPITool\n\nfrom pyopenagi.utils.utils import get_from_env\n\nimport requests\n\nimport json\n\nclass AirportSearch(BaseRapidAPITool):\n    def __init__(self):\n        super().__init__()\n        self.url = \"https://tripadvisor16.p.rapidapi.com/api/v1/flights/searchAirport\"\n        self.host_name = \"tripadvisor16.p.rapidapi.com\"\n        self.api_key = get_from_env(\"RAPID_API_KEY\")\n\n    def run(self, params: dict):\n        headers = {\n            \"X-RapidAPI-Key\": self.api_key,\n            \"X-RapidAPI-Host\": self.host_name\n        }\n        try:\n            self.query_string = {\n                \"query\": params[\"query\"],\n            }\n        except ValueError:\n            raise KeyError(\n                \"The keys in params do not match the excepted keys in params for tripadvisor search airport api. \"\n                \"Please make sure it contains the key: 'query'\"\n            )\n\n        # print(self.query_string)\n\n        response = requests.get(self.url, headers=headers, params=self.query_string).json()\n        return self.parse_result(response)\n\n    def parse_result(self, response) -> str:\n        limited_results = response['data'][:2]\n\n        simplified_results = []\n        for result in limited_results:\n            simplified_result = {\n                'name': result['name'],\n                'airportCode': result['airportCode'],\n                'coords': result['coords']\n            }\n            simplified_results.append(simplified_result)\n\n        return json.dumps(simplified_results)\n\n    def get_tool_call_format(self):\n        tool_call_format = {\n\t\t\t\"type\": \"function\",\n\t\t\t\"function\": {\n\t\t\t\t\"name\": \"airport_search\",\n\t\t\t\t\"description\": \"Search for an airport by query\",\n\t\t\t\t\"parameters\": {\n\t\t\t\t\t\"type\": \"object\",\n\t\t\t\t\t\"properties\": {\n\t\t\t\t\t\t\"query\": {\n\t\t\t\t\t\t\t\"type\": \"string\",\n\t\t\t\t\t\t\t\"description\": \"Search query for airport\"\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\t\"required\": [\n\t\t\t\t\t\t\"query\"\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t}\n\t\t}\n        return tool_call_format\n"
  },
  {
    "path": "pyopenagi/tools/trip_advisor/flight_search.py",
    "content": "from ..base import BaseRapidAPITool\n\nfrom pyopenagi.utils.utils import get_from_env\n\nimport requests\n\nimport json\n\nclass FlightSearch(BaseRapidAPITool):\n    def __init__(self):\n        super().__init__()\n        self.url = \"https://tripadvisor16.p.rapidapi.com/api/v1/flights/searchFlights\"\n        self.host_name = \"tripadvisor16.p.rapidapi.com\"\n        self.api_key = get_from_env(\"RAPID_API_KEY\")\n\n    def run(self, params: dict):\n        headers = {\n            \"X-RapidAPI-Key\": self.api_key,\n            \"X-RapidAPI-Host\": self.host_name\n        }\n\n        try:\n            self.query_string = {\n                \"sourceAirportCode\": params[\"sourceAirportCode\"],\n                \"date\": params[\"date\"],\n                \"destinationAirportCode\": params[\"destinationAirportCode\"],\n                \"itineraryType\": params[\"itineraryType\"],\n                \"sortOrder\": params[\"sortOrder\"],\n                \"classOfService\": params[\"classOfService\"],\n                \"returnDate\": params[\"returnDate\"]\n            }\n        except ValueError:\n            raise KeyError(\n                \"The keys in params do not match the excepted keys in params for tripadvisor search flight api. \"\n                \"Please make sure it contains following required keys: \"\n                \"sourceAirportCode\",\n                \"destinationAirportCode\",\n                \"itineraryType\",\n                \"sortOrder\",\n                \"classOfService\",\n                \"returnDate\",\n                \"date\"\n            )\n\n        response = requests.get(self.url, headers=headers, params=self.query_string).json()\n        return self.parse_result(response)\n\n    def parse_result(self, response) -> str:\n        # Accessing the 'flights' data from within the 'data' key\n        if 'data' in response and 'flights' in response['data']:\n            flights_data = response['data']['flights']\n            simplified_results = []\n            flight_count = 0\n            for flight in flights_data:\n                if flight_count >= 2:\n                    break\n                for segment in flight['segments']:\n                    for leg in segment['legs']:\n                        simplified_result = {\n                            'originStationCode': leg['originStationCode'],\n                            'destinationStationCode': leg['destinationStationCode'],\n                            'departureDateTime': leg['departureDateTime'],\n                            'arrivalDateTime': leg['arrivalDateTime'],\n                            'classOfService': leg['classOfService'],\n                            'marketingCarrierCode': leg['marketingCarrierCode'],\n                            'operatingCarrierCode': leg['operatingCarrierCode'],\n                            'flightNumber': leg['flightNumber'],\n                            'numStops': leg['numStops'],\n                            'distanceInKM': leg['distanceInKM'],\n                            'isInternational': leg['isInternational']\n                        }\n                        simplified_results.append(simplified_result)\n                flight_count += 1\n            return json.dumps(simplified_results)\n        else:\n            return json.dumps([])\n\n    def get_tool_call_format(self):\n        tool_call_format = {\n\t\t\t\"type\": \"function\",\n\t\t\t\"function\": {\n\t\t\t\t\"name\": \"flight_search\",\n\t\t\t\t\"description\": \"Provides details about a flight\",\n\t\t\t\t\"parameters\": {\n\t\t\t\t\t\"type\": \"object\",\n\t\t\t\t\t\"properties\": {\n\t\t\t\t\t\t\"sourceAirportCode\": {\n\t\t\t\t\t\t\t\"type\": \"string\",\n\t\t\t\t\t\t\t\"description\": \"The source airport code of the flight to search for\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"date\": {\n\t\t\t\t\t\t\t\"type\": \"string\",\n\t\t\t\t\t\t\t\"format\": \"date\",\n\t\t\t\t\t\t\t\"description\": \"The date of the flight\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"returnDate\": {\n\t\t\t\t\t\t\t\"type\": \"string\",\n\t\t\t\t\t\t\t\"format\": \"date\",\n\t\t\t\t\t\t\t\"description\": \"The return date of the flight\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"destinationAirportCode\": {\n\t\t\t\t\t\t\t\"type\": \"string\",\n\t\t\t\t\t\t\t\"description\": \"The destination airport code of the flight\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"itineraryType\": {\n\t\t\t\t\t\t\t\"type\": \"string\",\n\t\t\t\t\t\t\t\"enum\": [\n\t\t\t\t\t\t\t\t\"ONE_WAY\",\n\t\t\t\t\t\t\t\t\"ROUND_TRIP\"\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\"description\": \"The type of itinerary\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"sortOrder\": {\n\t\t\t\t\t\t\t\"type\": \"string\",\n\t\t\t\t\t\t\t\"enum\": [\n\t\t\t\t\t\t\t\t\"ML_BEST_VALUE\",\n\t\t\t\t\t\t\t\t\"DURATION\",\n\t\t\t\t\t\t\t\t\"PRICE\",\n\t\t\t\t\t\t\t\t\"EARLIEST_OUTBOUND_DEPARTURE\",\n\t\t\t\t\t\t\t\t\"EARLIEST_OUTBOUND_ARRIVAL\",\n\t\t\t\t\t\t\t\t\"LATEST_OUTBOUND_DEPARTURE\",\n\t\t\t\t\t\t\t\t\"LATEST_OUTBOUND_ARRIVAL\"\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\"description\": \"The order to sort the results\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"classOfService\": {\n\t\t\t\t\t\t\t\"type\": \"string\",\n\t\t\t\t\t\t\t\"enum\": [\n\t\t\t\t\t\t\t\t\"ECONOMY\",\n\t\t\t\t\t\t\t\t\"PREMIUM_ECONOMY\",\n\t\t\t\t\t\t\t\t\"BUSINESS\",\n\t\t\t\t\t\t\t\t\"FIRST\"\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\"description\": \"The class of service for the flight\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"numSeniors\": {\n\t\t\t\t\t\t\t\"type\": \"number\",\n\t\t\t\t\t\t\t\"description\": \"The number of seniors in the itinerary\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"numAdults\": {\n\t\t\t\t\t\t\t\"type\": \"number\",\n\t\t\t\t\t\t\t\"description\": \"The number of adults in the itinerary\"\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\t\"required\": [\n\t\t\t\t\t\t\"sourceAirportCode\",\n\t\t\t\t\t\t\"date\",\n\t\t\t\t\t\t\"destinationAirportCode\",\n\t\t\t\t\t\t\"itineraryType\",\n\t\t\t\t\t\t\"sortOrder\",\n\t\t\t\t\t\t\"classOfService\",\n\t\t\t\t\t\t\"numSeniors\",\n\t\t\t\t\t\t\"numAdults\",\n\t\t\t\t\t\t\"returnDate\"\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t}\n\t\t}\n        return tool_call_format\n"
  },
  {
    "path": "pyopenagi/tools/trip_advisor/get_hotel_details.py",
    "content": "from ..base import BaseRapidAPITool\n\nfrom pyopenagi.utils.utils import get_from_env\n\nimport requests\n\nimport json\n\nclass GetHotelDetails(BaseRapidAPITool):\n    def __init__(self):\n        super().__init__()\n        self.url = \"https://tripadvisor16.p.rapidapi.com/api/v1/hotels/getHotelDetails\"\n        self.host_name = \"tripadvisor16.p.rapidapi.com\"\n        self.api_key = get_from_env(\"RAPID_API_KEY\")\n\n    def run(self, params: dict):\n        headers = {\n            \"X-RapidAPI-Key\": self.api_key,\n            \"X-RapidAPI-Host\": self.host_name\n        }\n\n        try:\n            self.query_string = {\n                \"id\": params[\"id\"],\n                \"checkIn\": params[\"checkIn\"],\n                \"checkOut\": params[\"checkOut\"],\n            }\n        except ValueError:\n            raise KeyError(\n                \"The keys in params do not match the excepted keys in params for tripadvisor get hotel details api. \"\n                \"Please make sure it contains following required keys: \"\n                \"id\",\n                \"checkIn\",\n                \"checkOut\",\n            )\n\n        response = requests.get(self.url, headers=headers, params=self.query_string).json()\n        return self.parse_result(response)\n\n    def parse_result(self, response) -> str:\n        if 'data' in response:\n            hotel_data = response['data']\n            relevant_info = {\n                'name': hotel_data.get('title', ''),\n                'rating': hotel_data.get('rating', ''),\n                'address': hotel_data.get('location', {}).get('address', ''),\n                'amenities': [amenity['title'] for amenity in hotel_data.get('about', {}).get('content', []) if amenity['title'] == 'Amenities'],\n                'description': hotel_data.get('about', {}).get('content', [{}])[0].get('content', ''),\n                'restaurantsNearby': [{\n                    'title': hotel_data.get('restaurantsNearby', {}).get('content', [{}])[0].get('title', ''),\n                    'rating': hotel_data.get('restaurantsNearby', {}).get('content', [{}])[0].get('bubbleRating', {}).get('rating', ''),\n                    'primaryInfo': hotel_data.get('restaurantsNearby', {}).get('content', [{}])[0].get('primaryInfo', ''),\n                    'distance': hotel_data.get('restaurantsNearby', {}).get('content', [{}])[0].get('distance', ''),\n                }],\n                'attractionsNearby': [{\n                    'title': hotel_data.get('attractionsNearby', {}).get('content', [{}])[0].get('title', ''),\n                    'rating': hotel_data.get('attractionsNearby', {}).get('content', [{}])[0].get('bubbleRating', {}).get('rating', ''),\n                    'primaryInfo': hotel_data.get('attractionsNearby', {}).get('content', [{}])[0].get('primaryInfo', ''),\n                    'distance': hotel_data.get('attractionsNearby', {}).get('content', [{}])[0].get('distance', ''),\n                }]\n            }\n            return json.dumps(relevant_info)\n        else:\n            return json.dumps({})\n\n    def get_tool_call_format(self):\n        tool_call_format = {\n\t\t\t\"type\": \"function\",\n\t\t\t\"function\": {\n\t\t\t\t\"name\": \"get_hotel_details\",\n\t\t\t\t\"description\": \"Provides details about a hotel\",\n\t\t\t\t\"parameters\": {\n\t\t\t\t\t\"type\": \"object\",\n\t\t\t\t\t\"properties\": {\n\t\t\t\t\t\t\"id\": {\n\t\t\t\t\t\t\t\"type\": \"string\",\n\t\t\t\t\t\t\t\"description\": \"The ID of the hotel to get details for\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"checkIn\": {\n\t\t\t\t\t\t\t\"type\": \"string\",\n\t\t\t\t\t\t\t\"format\": \"date\",\n\t\t\t\t\t\t\t\"description\": \"The check in date\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"checkOut\": {\n\t\t\t\t\t\t\t\"type\": \"string\",\n\t\t\t\t\t\t\t\"format\": \"date\",\n\t\t\t\t\t\t\t\"description\": \"The check out date\"\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\t\"required\": [\n\t\t\t\t\t\t\"id\",\n\t\t\t\t\t\t\"checkIn\",\n\t\t\t\t\t\t\"checkOut\"\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t}\n\t\t}\n        return tool_call_format\n"
  },
  {
    "path": "pyopenagi/tools/trip_advisor/get_restaurant_details.py",
    "content": "from ..base import BaseRapidAPITool\n\nfrom pyopenagi.utils.utils import get_from_env\n\nimport requests\n\nimport json\n\nclass GetRestaurantDetails(BaseRapidAPITool):\n    def __init__(self):\n        super().__init__()\n        self.url = \"https://tripadvisor16.p.rapidapi.com/api/v1/restaurant/getRestaurantDetails\"\n        self.host_name = \"tripadvisor16.p.rapidapi.com\"\n        self.api_key = get_from_env(\"RAPID_API_KEY\")\n\n    def run(self, params: dict):\n        headers = {\n            \"X-RapidAPI-Key\": self.api_key,\n            \"X-RapidAPI-Host\": self.host_name\n        }\n\n        try:\n            self.query_string = {\n                \"restaurantsId\": params[\"restaurantsId\"],\n            }\n        except ValueError:\n            raise KeyError(\n                \"The keys in params do not match the excepted keys in params for tripadvisor get restaurant details api. \"\n                \"Please make sure it contains the key: 'restaurantsID'\"\n            )\n\n        response = requests.get(self.url, headers=headers, params=self.query_string).json()\n        return self.parse_result(response)\n\n\n    def parse_result(self, response) -> str:\n        location = response[\"data\"][\"location\"]\n\n        useful_info = {\n            \"name\": location.get(\"name\"),\n            \"latitude\": location.get(\"latitude\"),\n            \"longitude\": location.get(\"longitude\"),\n            \"num_reviews\": location.get(\"num_reviews\"),\n            \"rating\": location.get(\"rating\"),\n            \"price_level\": location.get(\"price_level\"),\n            \"address\": location.get(\"address\"),\n            \"phone\": location.get(\"phone\"),\n            \"website\": location.get(\"website\"),\n            \"cuisine\": [cuisine[\"name\"] for cuisine in location.get(\"cuisine\", [])],\n            \"hours\": location.get(\"hours\", {}).get(\"week_ranges\", [])\n            }\n        return json.dumps(useful_info)\n\n    def get_tool_call_format(self):\n        tool_call_format = {\n\t\t\t\"type\": \"function\",\n\t\t\t\"function\": {\n\t\t\t\t\"name\": \"get_restaurant_details\",\n\t\t\t\t\"description\": \"Provides details about a restaurant\",\n\t\t\t\t\"parameters\": {\n\t\t\t\t\t\"type\": \"object\",\n\t\t\t\t\t\"properties\": {\n\t\t\t\t\t\t\"restaurantsId\": {\n\t\t\t\t\t\t\t\"type\": \"string\",\n\t\t\t\t\t\t\t\"description\": \"The ID of the restaurant to get details for\"\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\t\"required\": [\n\t\t\t\t\t\t\"restaurantsId\"\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t}\n\t\t}\n        return tool_call_format\n"
  },
  {
    "path": "pyopenagi/tools/trip_advisor/hotel_location_search.py",
    "content": "from ..base import BaseRapidAPITool\n\nfrom pyopenagi.utils.utils import get_from_env\n\nimport requests\n\nimport json\n\nclass HotelLocationSearch(BaseRapidAPITool):\n    def __init__(self):\n        super().__init__()\n        self.url = \"https://tripadvisor16.p.rapidapi.com/api/v1/hotels/searchLocation\"\n        self.host_name = \"tripadvisor16.p.rapidapi.com\"\n        self.api_key = get_from_env(\"RAPID_API_KEY\")\n\n    def run(self, params: dict):\n        headers = {\n            \"X-RapidAPI-Key\": self.api_key,\n            \"X-RapidAPI-Host\": self.host_name\n        }\n        try:\n            self.query_string = {\n                \"query\": params[\"query\"],\n            }\n        except ValueError:\n            raise KeyError(\n                \"The keys in params do not match the excepted keys in params for tripadvisor search hotel location api. \"\n                \"Please make sure it contains the key: 'query'\"\n            )\n\n        # print(self.query_string)\n\n        response = requests.get(self.url, headers=headers, params=self.query_string).json()\n        return json.dumps(response)\n\n    def parse_result(self, response) -> str:\n        raise NotImplementedError\n\n    def get_tool_call_format(self):\n        tool_call_format = {\n\t\t\t\"type\": \"function\",\n\t\t\t\"function\": {\n\t\t\t\t\"name\": \"hotel_location_search\",\n\t\t\t\t\"description\": \"Search for a hotel location by query\",\n\t\t\t\t\"parameters\": {\n\t\t\t\t\t\"type\": \"object\",\n\t\t\t\t\t\"properties\": {\n\t\t\t\t\t\t\"query\": {\n\t\t\t\t\t\t\t\"type\": \"string\",\n\t\t\t\t\t\t\t\"description\": \"Search query for hotel location\"\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\t\"required\": [\n\t\t\t\t\t\t\"query\"\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t}\n\t\t}\n        return tool_call_format\n"
  },
  {
    "path": "pyopenagi/tools/trip_advisor/hotel_search.py",
    "content": "from ..base import BaseRapidAPITool\n\nfrom pyopenagi.utils.utils import get_from_env\n\nimport requests\n\nimport json\n\nclass HotelSearch(BaseRapidAPITool):\n    def __init__(self):\n        super().__init__()\n        self.url = \"https://tripadvisor16.p.rapidapi.com/api/v1/hotels/searchHotels\"\n        self.host_name = \"tripadvisor16.p.rapidapi.com\"\n        self.api_key = get_from_env(\"RAPID_API_KEY\")\n\n    def run(self, params: dict):\n        headers = {\n            \"X-RapidAPI-Key\": self.api_key,\n            \"X-RapidAPI-Host\": self.host_name\n        }\n\n        try:\n            self.query_string = {\n                \"geoId\": params[\"geoId\"],\n                \"checkIn\": params[\"checkIn\"],\n                \"checkOut\": params[\"checkOut\"],\n            }\n        except ValueError:\n            raise KeyError(\n                \"The keys in params do not match the excepted keys in params for tripadvisor search hotel api. \"\n                \"Please make sure it contains following required keys: \"\n                \"geoId\",\n                \"checkIn\",\n                \"checkOut\",\n            )\n\n        response = requests.get(self.url, headers=headers, params=self.query_string).json()\n        return self.parse_result(response)\n\n\n    def parse_result(self, response) -> str:\n        if 'data' in response and 'data' in response['data']:\n            hotels_data = response['data']['data'][:2]\n            relevant_info = []\n            for hotel in hotels_data:\n                relevant_info.append({\n                    'id': hotel['id'],\n                    'title': hotel['title'],\n                    'secondaryInfo': hotel['secondaryInfo'],\n                    'bubbleRating': hotel['bubbleRating'],\n                    'priceForDisplay': hotel['priceForDisplay'],\n                    'priceDetails': hotel['priceDetails'],\n                    'priceSummary': hotel['priceSummary']\n                })\n            return json.dumps(relevant_info)\n        else:\n            return json.dumps([])\n\n    def get_tool_call_format(self):\n        tool_call_format = {\n\t\t\t\"type\": \"function\",\n\t\t\t\"function\": {\n\t\t\t\t\"name\": \"hotel_search\",\n\t\t\t\t\"description\": \"Provides details about a hotel\",\n\t\t\t\t\"parameters\": {\n\t\t\t\t\t\"type\": \"object\",\n\t\t\t\t\t\"properties\": {\n\t\t\t\t\t\t\"geoId\": {\n\t\t\t\t\t\t\t\"type\": \"string\",\n\t\t\t\t\t\t\t\"description\": \"The geoId of the hotel to search for\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"checkIn\": {\n\t\t\t\t\t\t\t\"type\": \"string\",\n\t\t\t\t\t\t\t\"format\": \"date\",\n\t\t\t\t\t\t\t\"description\": \"The check in date\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"checkOut\": {\n\t\t\t\t\t\t\t\"type\": \"string\",\n\t\t\t\t\t\t\t\"format\": \"date\",\n\t\t\t\t\t\t\t\"description\": \"The check out date\"\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\t\"required\": [\n\t\t\t\t\t\t\"geoId\",\n\t\t\t\t\t\t\"checkIn\",\n\t\t\t\t\t\t\"checkOut\"\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t}\n\t\t}\n        return tool_call_format\n"
  },
  {
    "path": "pyopenagi/tools/trip_advisor/restaurant_location_search.py",
    "content": "from ..base import BaseRapidAPITool\n\nfrom pyopenagi.utils.utils import get_from_env\n\nimport requests\n\nimport json\n\nclass RestaurantLocationSearch(BaseRapidAPITool):\n    def __init__(self):\n        super().__init__()\n        self.url = \"https://tripadvisor16.p.rapidapi.com/api/v1/restaurant/searchLocation\"\n        self.host_name = \"tripadvisor16.p.rapidapi.com\"\n        self.api_key = get_from_env(\"RAPID_API_KEY\")\n\n    def run(self, params: dict):\n        headers = {\n            \"X-RapidAPI-Key\": self.api_key,\n            \"X-RapidAPI-Host\": self.host_name\n        }\n        try:\n            self.query_string = {\n                \"query\": params[\"query\"],\n            }\n        except ValueError:\n            raise KeyError(\n                \"The keys in params do not match the excepted keys in params for tripadvisor search restaurant location api. \"\n                \"Please make sure it contains the key: 'query'\"\n            )\n\n        # print(self.query_string)\n\n        response = requests.get(self.url, headers=headers, params=self.query_string).json()\n        return self.parse_result(response)\n\n    def parse_result(self, response) -> str:\n        limited_results = response['data'][:2]\n\n        simplified_results = []\n        for result in limited_results:\n            simplified_result = {\n                'locationId': result['locationId'],\n                'localizedName': result['localizedName'],\n                'latitude': result['latitude'],\n                'longitude': result['longitude']\n            }\n            simplified_results.append(simplified_result)\n\n        return json.dumps(simplified_results)\n\n    def get_tool_call_format(self):\n        tool_call_format = {\n\t\t\t\"type\": \"function\",\n\t\t\t\"function\": {\n\t\t\t\t\"name\": \"restaurant_location_search\",\n\t\t\t\t\"description\": \"Search for a restaurant location by query\",\n\t\t\t\t\"parameters\": {\n\t\t\t\t\t\"type\": \"object\",\n\t\t\t\t\t\"properties\": {\n\t\t\t\t\t\t\"query\": {\n\t\t\t\t\t\t\t\"type\": \"string\",\n\t\t\t\t\t\t\t\"description\": \"Search query for restaurant location\"\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\t\"required\": [\n\t\t\t\t\t\t\"query\"\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t}\n\t\t}\n        return tool_call_format\n"
  },
  {
    "path": "pyopenagi/tools/trip_advisor/restaurant_search.py",
    "content": "\n\nfrom ..base import BaseRapidAPITool\n\nfrom pyopenagi.utils.utils import get_from_env\n\nimport requests\n\nimport json\n\nclass RestaurantSearch(BaseRapidAPITool):\n    def __init__(self):\n        super().__init__()\n        self.url = \"https://tripadvisor16.p.rapidapi.com/api/v1/restaurant/searchRestaurants\"\n        self.host_name = \"tripadvisor16.p.rapidapi.com\"\n        self.api_key = get_from_env(\"RAPID_API_KEY\")\n\n    def run(self, params: dict):\n        headers = {\n            \"X-RapidAPI-Key\": self.api_key,\n            \"X-RapidAPI-Host\": self.host_name\n        }\n\n        try:\n            self.query_string = {\n                \"locationId\": params[\"locationId\"]\n            }\n        except ValueError:\n            raise KeyError(\n                \"The keys in params do not match the excepted keys in params for tripadvisor search restaurant api. \"\n                \"Please make sure it contains following required keys: \"\n                \"locationID\",\n            )\n\n        response = requests.get(self.url, headers=headers, params=self.query_string).json()\n        return self.parse_result(response)\n\n    def parse_result(self, response) -> str:\n        limited_results = response['data']['data'][:2]\n\n        simplified_results = []\n        for result in limited_results:\n            simplified_result = {\n                'restaurantsId': result['restaurantsId'],\n                'name': result['name'],\n                'averageRating': result['averageRating'],\n                'userReviewCount': result['userReviewCount'],\n                'priceTag': result['priceTag'],\n                'establishmentTypeAndCuisineTags': result['establishmentTypeAndCuisineTags']\n            }\n            simplified_results.append(simplified_result)\n\n        return json.dumps(simplified_results)\n\n    def get_tool_call_format(self):\n        tool_call_format = {\n\t\t\t\"type\": \"function\",\n\t\t\t\"function\": {\n\t\t\t\t\"name\": \"restaurant_search\",\n\t\t\t\t\"description\": \"Search for a restaurant by locationID\",\n\t\t\t\t\"parameters\": {\n\t\t\t\t\t\"type\": \"object\",\n\t\t\t\t\t\"properties\": {\n\t\t\t\t\t\t\"locationId \": {\n\t\t\t\t\t\t\t\"type\": \"string\",\n\t\t\t\t\t\t\t\"description\": \"The locationID of the restaurant to search for\"\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\t\"required\": [\n\t\t\t\t\t\t\"locationId\"\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t}\n\t\t}\n        return tool_call_format\n"
  },
  {
    "path": "pyopenagi/tools/wikipedia/wikipedia.py",
    "content": "from ..base import BaseTool\n# from langchain_core.documents import Document\nfrom typing import Optional, Any\nclass Wikipedia(BaseTool):\n    \"\"\"Wikipedia tool, refactored from langchain.\n\n    To use, you should have the ``wikipedia`` python package installed.\n    This wrapper will use the Wikipedia API to conduct searches and\n    fetch page summaries. By default, it will return the page summaries\n    of the top-k results.\n    It limits the Document content by doc_content_chars_max.\n    \"\"\"\n    def __init__(self):\n        super().__init__()\n        self.WIKIPEDIA_MAX_QUERY_LENGTH = 300\n        self.top_k_results = 3\n        self.lang = \"en\"\n        self.load_all_available_meta: bool = False\n        self.doc_content_chars_max: int = 4000\n        self.wiki_client = self.build_client()\n\n    def build_client(self):\n        try:\n            import wikipedia\n\n            wikipedia.set_lang(self.lang)\n\n        except ImportError:\n            raise ImportError(\n                \"Could not import wikipedia python package. \"\n                \"Please install it with `pip install wikipedia`.\"\n            )\n        return wikipedia\n\n    def run(self, params) -> str:\n        \"\"\"Run Wikipedia search and get page summaries.\"\"\"\n        query = params[\"query\"]\n        # if not isinstance(query, dict) or 'query' not in query:\n        #     raise TypeError(\"Query must be a dictionary with a 'query' key\")\n        # query_str = query['query'][:self.WIKIPEDIA_MAX_QUERY_LENGTH]  # Extract and slice the query string\n        page_titles = self.wiki_client.search(query, results=self.top_k_results)\n        summaries = []\n        for page_title in page_titles[: self.top_k_results]:\n            if wiki_page := self._fetch_page(page_title):\n                if summary := self._formatted_page_summary(page_title, wiki_page):\n                    summaries.append(summary)\n        if not summaries:\n            return \"No good Wikipedia Search Result was found\"\n        return \"\\n\\n\".join(summaries)[: self.doc_content_chars_max]\n\n    @staticmethod\n    def _formatted_page_summary(page_title: str, wiki_page: Any) -> Optional[str]:\n        return f\"Page: {page_title}\\nSummary: {wiki_page.summary}\"\n\n    def get_tool_call_format(self):\n        tool_call_format = {\n\t\t\t\"type\": \"function\",\n\t\t\t\"function\": {\n\t\t\t\t\"name\": \"wikipedia\",\n\t\t\t\t\"description\": \"Provides relevant information about the destination\",\n\t\t\t\t\"parameters\": {\n\t\t\t\t\t\"type\": \"object\",\n\t\t\t\t\t\"properties\": {\n\t\t\t\t\t\t\"query\": {\n\t\t\t\t\t\t\t\"type\": \"string\",\n\t\t\t\t\t\t\t\"description\": \"Search query for Wikipedia\"\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\t\"required\": [\n\t\t\t\t\t\t\"query\"\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t}\n\t\t}\n        return tool_call_format\n"
  },
  {
    "path": "pyopenagi/tools/wolfram/wolfram_alpha.py",
    "content": "from ..base import BaseTool\n\nfrom pyopenagi.utils.utils import get_from_env\nclass WolframAlpha(BaseTool):\n    \"\"\"Wolfram Alpha Tool, refactored from langchain.\n\n    Docs for using:\n\n    1. Go to wolfram alpha and sign up for a developer account\n    2. Create an app and get your APP ID\n    3. Save your APP ID into WOLFRAM_ALPHA_APPID env variable\n    4. pip install wolframalpha\n\n    \"\"\"\n    def __init__(self):\n        super().__init__()\n        self.wolfram_alpha_appid = get_from_env(\"WOLFRAM_ALPHA_APPID\")\n        self.wolfram_client = self.build_client()\n\n    def build_client(self):\n        try:\n            import wolframalpha\n\n        except ImportError:\n            raise ImportError(\n                \"wolframalpha is not installed. \"\n                \"Please install it with `pip install wolframalpha`\"\n            )\n        client = wolframalpha.Client(self.wolfram_alpha_appid)\n        return client\n\n    def run(self, query: str) -> str:\n        \"\"\"Run query through WolframAlpha and parse result.\"\"\"\n        res = self.wolfram_client.query(query)\n\n        try:\n            assumption = next(res.pods).text\n            answer = next(res.results).text\n        except StopIteration:\n            return \"Wolfram Alpha wasn't able to answer it\"\n\n        if answer is None or answer == \"\":\n            # We don't want to return the assumption alone if answer is empty\n            return \"No good Wolfram Alpha Result was found\"\n        else:\n            return f\"Assumption: {assumption} \\nAnswer: {answer}\"\n\n\n    def get_tool_call_format(self):\n        tool_call_format = {\n            \"type\": \"function\",\n            \"function\": {\n                \"name\": \"wolfram_alpha\",\n                \"description\": \"Use specific mathematical knowledge (algebra, calculus, geometry, etc) to answer the given query\",\n                \"parameters\": {\n                    \"type\": \"object\",\n                    \"properties\": {\n                        \"query\": {\n                            \"type\": \"string\",\n                            \"description\": \"the abstracted mathematical query that needs to be answered\"\n                        }\n                    },\n                    \"required\": [\n                        \"query\"\n                    ]\n                }\n            }\n        }\n        return tool_call_format\n"
  },
  {
    "path": "pyopenagi/tools/words_api/words_api.py",
    "content": "from ..base import BaseRapidAPITool\n\n# from pydantic import root_validator\n\nfrom pyopenagi.utils.utils import get_from_env\n\nimport requests\n\nSUPPORTED_APIS = [\n    \"typeOf\", \"hasTypes\", \"partOf\", \"hasParts\",\n    \"instanceOf\", \"hasInstances\", \"similarTo\",\n    \"also\", \"entails\", \"memberOf\", \"hasMembers\",\n    \"substanceOf\", \"hasSubstances\", \"inCategory\",\n    \"hasCategories\", \"usageOf\", \"hasUsages\",\n    \"inRegion\", \"regionOf\", \"pertainsTo\", \"synonyms\",\n    \"examples\", \"antonyms\", \"pronunciation\",\n]\n\nclass WordsAPI(BaseRapidAPITool):\n    def __init__(self):\n        super().__init__()\n        self.base_url = \"https://wordsapiv1.p.rapidapi.com/words/\"\n        self.url = self.base_url\n        self.host_name = \"wordsapiv1.p.rapidapi.com\"\n        self.api_key = get_from_env(\"RAPID_API_KEY\")\n\n    def run(self, params):\n        headers = {\n            \"X-RapidAPI-Key\": self.api_key,\n            \"X-RapidAPI-Host\": self.host_name\n        }\n        try:\n            self.word = params[\"word\"]\n            self.api_name = params[\"api_name\"]\n        except KeyError:\n            raise KeyError(\n                \"The keys in params do not match the excepted keys in params for words api. \"\n                \"Please make sure it contains two keys: 'words' and 'api_name'\"\n            )\n\n        if not self.is_supported(self.api_name):\n            raise ValueError(\n                f\"{self.api_name} is currently not supported!\"\n            )\n\n        self.url = f\"{self.base_url}{self.word}/{self.api_name}\"\n        response = requests.get(self.url, headers=headers).json()\n        result = self.parse_result(response)\n        return result\n\n    def parse_result(self, response) -> str:\n        # fail response: {'success': False, 'message': 'word not found'}\n        if \"success\" in response and not response[\"success\"]:\n            return response[\"message\"]\n\n        return response[\"word\"] + \" \" + self.api_name + \" [\" + \",\".join(response[self.api_name]) + \"]\"\n\n    def is_supported(self, api_name):\n        return api_name in SUPPORTED_APIS\n"
  },
  {
    "path": "pyopenagi/utils/README.md",
    "content": "# pyopenagi/utils\n\nHelper utils that are re-used in AIOS.\n\nThese are various tools that we use in our internal implementations.\n\nIn the future they shouldn't be copy pasted to AIOS.\n"
  },
  {
    "path": "pyopenagi/utils/__init__.py",
    "content": ""
  },
  {
    "path": "pyopenagi/utils/chat_template.py",
    "content": "class Query:\n    def __init__(self,\n            messages,\n            tools = None,\n            message_return_type = \"text\"\n        ) -> None:\n        \"\"\"Query format\n\n        Args:\n            messages (list):\n            [\n                {\"role\": \"xxx\", content_key: content_value}\n            ]\n            tools (optional): tools that are used for function calling. Defaults to None.\n        \"\"\"\n        self.messages = messages\n        self.tools = tools\n        self.message_return_type = message_return_type\n\nclass Response:\n    def __init__(\n            self,\n            response_message,\n            tool_calls: list = None\n        ) -> None:\n        \"\"\"Response format\n\n        Args:\n            response_message (str): \"generated_text\"\n            tool_calls (list, optional):\n            [\n                {\"name\": \"xxx\", \"parameters\": {}}\n            ].\n            Default to None.\n        \"\"\"\n        self.response_message = response_message\n        self.tool_calls = tool_calls\n"
  },
  {
    "path": "pyopenagi/utils/commands/top.py",
    "content": ""
  },
  {
    "path": "pyopenagi/utils/compressor.py",
    "content": "import zlib\n\nclass Compressor:\n    def __init__(self) -> None:\n        pass\n\n    def compress(self, data):\n        pass\n\n    def decompress(self, compressed_data):\n        pass\n\nclass ZLIBCompressor(Compressor):\n    def __init__(self) -> None:\n        pass\n\n    def compress(self, data):\n        compressed_data = zlib.compress(data.encode('utf-8'))\n        return compressed_data\n\n    def decompress(self, compressed_data):\n        decompressed_data = zlib.decompress(compressed_data)\n        return decompressed_data.decode('utf-8')\n"
  },
  {
    "path": "pyopenagi/utils/logger.py",
    "content": "import click\n\nimport os\n\nfrom datetime import datetime\n\nclass BaseLogger:\n    def __init__(self,\n            logger_name,\n            log_mode = \"console\",\n        ) -> None:\n        self.logger_name = logger_name\n        self.log_mode = log_mode\n        self.log_file = self.load_log_file() if log_mode == \"file\" else None\n\n        self.level_color = dict()\n\n    def log(self, content, level):\n        if self.log_mode == \"console\":\n            self.log_to_console(content, level)\n        else:\n            assert self.log_mode == \"file\" and self.log_file is not None\n            self.log_to_file(content, self.log_file)\n\n    def load_log_file(self):\n        pass\n\n    def log_to_console(self, content, level):\n        # print(content)\n        click.secho(f\"[{self.logger_name}] \" + content, fg=self.level_color[level])\n\n    def log_to_file(self, content, log_file):\n        with open(log_file, \"a\") as w:\n            w.writelines(content)\n\nclass SchedulerLogger(BaseLogger):\n    def __init__(self, logger_name, log_mode=\"console\") -> None:\n        super().__init__(logger_name, log_mode)\n        self.level_color = {\n            \"execute\": \"green\",\n            \"suspend\": \"yellow\",\n            \"info\": \"white\"\n        }\n\n    def load_log_file(self):\n        date_time = datetime.now().strftime(\"%Y-%m-%d %H:%M:%S\")\n        log_dir = os.path.join(os.getcwd(), \"logs\", \"scheduler\")\n        if not os.path.exists(log_dir):\n            os.makedirs(log_dir)\n        log_file = os.path.join(log_dir, f\"{date_time}.txt\")\n        return log_file\n\n\nclass AgentLogger(BaseLogger):\n    def __init__(self, logger_name, log_mode=\"console\") -> None:\n        super().__init__(logger_name, log_mode)\n        self.level_color = {\n            \"info\": (248, 246, 227), # white\n            \"executing\": (217, 237, 191), # green\n            \"suspending\": (255, 235, 178), # yellow\n            \"done\": (122, 162, 227) # blue\n        }\n\n    def load_log_file(self):\n        date_time = datetime.now().strftime(\"%Y-%m-%d %H:%M:%S\")\n        log_dir = os.path.join(os.getcwd(), \"logs\", \"agents\", self.logger_name)\n        if not os.path.exists(log_dir):\n            os.makedirs(log_dir)\n        log_file = os.path.join(log_dir, f\"{date_time}.txt\")\n        return log_file\n\n\nclass LLMKernelLogger(BaseLogger):\n    def __init__(self, logger_name, log_mode=\"console\") -> None:\n        super().__init__(logger_name, log_mode)\n        self.level_color = {\n            \"info\": (246, 245, 242),\n            \"executing\": (65, 176, 110), # green\n            \"suspending\": (255, 201, 74), # yellow\n            \"done\": (122, 162, 227) # blue\n        }\n\n    def log_to_console(self, content, level):\n        # print(content)\n        click.secho(f\"[\\U0001F916{self.logger_name}] \" + content, fg=self.level_color[level], bold=True)\n\n    def load_log_file(self):\n        date_time = datetime.now().strftime(\"%Y-%m-%d %H:%M:%S\")\n        log_dir = os.path.join(os.getcwd(), \"logs\", \"llm_kernel\", self.logger_name)\n        if not os.path.exists(log_dir):\n            os.makedirs(log_dir)\n        log_file = os.path.join(log_dir, f\"{date_time}.txt\")\n        return log_file\n"
  },
  {
    "path": "pyopenagi/utils/utils.py",
    "content": "import argparse\n\nimport os\nimport shutil\n\nimport json\n\nfrom typing import Dict, Any, Optional\n\nimport re\n\n# logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')\n# logger = logging.getLogger(__name__)\n\ndef parse_global_args():\n    parser = argparse.ArgumentParser(description=\"Parse global parameters\")\n    parser.add_argument('--llm_name', type=str, default=\"gpt-4o-mini\", help=\"Specify the LLM name of AIOS\")\n    parser.add_argument('--max_gpu_memory', type=json.loads, help=\"Max gpu memory allocated for the LLM\")\n    parser.add_argument('--eval_device', type=str, help=\"Evaluation device\")\n    parser.add_argument('--max_new_tokens', type=int, default=256, help=\"The maximum number of new tokens for generation\")\n    parser.add_argument(\"--llm_kernel_log_mode\", type=str, default=\"console\", choices=[\"console\", \"file\"])\n    parser.add_argument(\"--use_backend\", type=str, default=\"ollama\", choices=[\"ollama\", \"vllm\"])\n\n    return parser\n\ndef extract_before_parenthesis(s: str) -> str:\n    match = re.search(r'^(.*?)\\([^)]*\\)', s)\n    return match.group(1) if match else s\n\ndef get_from_dict_or_env(\n    data: Dict[str, Any], key: str, env_key: str, default: Optional[str] = None\n) -> str:\n    \"\"\"Get a value from a dictionary or an environment variable.\"\"\"\n    if key in data and data[key]:\n        return data[key]\n    else:\n        return get_from_env(key, env_key, default=default)\n\n\ndef get_from_env(env_key: str, default: Optional[str] = None) -> str:\n    \"\"\"Get a value from an environment variable.\"\"\"\n    if env_key in os.environ and os.environ[env_key]:\n        return os.environ[env_key]\n    elif default is not None:\n        return default\n    else:\n        raise ValueError(\n            f\"Did not find {env_key}, please add an environment variable\"\n            f\" `{env_key}` which contains it. \"\n        )\n\nclass Logger:\n    def __init__(self, log_mode) -> None:\n        self.log_mode = log_mode\n\n    def log(self, info, path=None):\n        if self.log_mode == \"console\":\n            print(info)\n        else:\n            assert self.log_mode == \"file\"\n            with open(path, \"w\") as w:\n                w.write(info + \"\\n\")\n\ndef delete_directories(root_dir, target_dirs):\n    \"\"\"\n    Recursively deletes directories with names in target_dirs starting from root_dir.\n    \"\"\"\n    for dirpath, dirnames, filenames in os.walk(root_dir, topdown=False):\n        for dirname in dirnames:\n            if dirname in target_dirs:\n                full_path = os.path.join(dirpath, dirname)\n                # print(f\"Deleting {full_path}...\")\n                shutil.rmtree(full_path, ignore_errors=True)\n"
  },
  {
    "path": "pyproject.toml",
    "content": "[build-system]\nbuild-backend = \"hatchling.build\"\nrequires = [\"hatchling\", \"hatch-requirements-txt\"]\n\n[project]\n\ndynamic = [\"dependencies\"]\n\ndescription = \"OpenAGI: Package for AI Agent Creation\"\nkeywords = [\"llm\", \"agi\"]\nlicense = {file = \"LICENSE\"}\n\nname = \"pyopenagi\"\nreadme = \"README.md\"\nrequires-python = \">=3.9\"\nversion = \"0.0.11\"\n\nclassifiers = [\n  \"Development Status :: 3 - Alpha\",\n  \"Intended Audience :: Developers\",\n  \"Topic :: Software Development :: Libraries :: Python Modules\",\n  \"License :: OSI Approved :: MIT License\",\n  \"Programming Language :: Python :: 3\",\n  \"Programming Language :: Python :: 3.9\",\n  \"Programming Language :: Python :: 3.10\",\n  \"Programming Language :: Python :: 3.11\",\n]\n\n[project.urls]\nHomepage = \"https://github.com/agiresearch/OpenAGI\"\nRepository = \"https://github.com/agiresearch/OpenAGI.git\"\n\"Tools Docs\" = \"https://github.com/agiresearch/OpenAGI/tools.md\"\n\n\n[tool.hatch.build]\nexclude = [\"research/\", \"pyopenagi.egg-info/\", \"dist\", \"__pycache__/\", \".pytest_cache/\"]\n\n[tool.hatch.metadata.hooks.requirements_txt]\nfiles = [\"requirements.txt\"]\n\n[tool.hatch.build.targets.wheel]\npackages = [\"pyopenagi\"]\n"
  },
  {
    "path": "requirements-dev.txt",
    "content": "-r requirements.txt\npre-commit\npytest\n"
  },
  {
    "path": "requirements.txt",
    "content": "python-dotenv\nRequests\nPympler==1.0.1\nclick==8.1.7\npython-dotenv==1.0.0\nbeautifulsoup4\nplaywright\n"
  },
  {
    "path": "tests/README.md",
    "content": "# tests\n\nThis directory contains tests you can use to test specific features of the project so you can figure out which specific parts work easier. \n\nFor example, test_agent_creation.py simply tests the AgentProcess ability to hold agents.\n\nWe want to use error code to differentiate between successful and failed tests in the future.\n"
  },
  {
    "path": "tests/__init__.py",
    "content": ""
  },
  {
    "path": "tests/test_agent_creation.py",
    "content": "# make sure we can create agents\n\nfrom pyopenagi.agents.agent_process import AgentProcess\nfrom pyopenagi.utils.chat_template import Query\n\ndef test_agent_creation():\n    agent_process = AgentProcess(\n        agent_name=\"example/academic_agent\",\n        query=Query(\n            messages = [\n                {\"role\": \"user\", \"content\": \"Summarize researches of quantum computing in recent five years.\"}\n            ]\n        )\n    )\n    # Use plain assert statements for testing conditions\n    assert agent_process.agent_name == \"example/academic_agent\", \"Agent name does not match\"\n    # Add more assertions here as necessary to validate the properties of the agent_process object\n"
  },
  {
    "path": "tests/test_tools/README.md",
    "content": "# test/test_tools\n\nThis tests specific tools the agents can use and makes sure they are working. Each tool has its own test.\n"
  },
  {
    "path": "tests/test_tools/test_currency_converter.py",
    "content": "import os\nimport pytest\n\nfrom pyopenagi.tools.currency_converter.currency_converter import CurrencyConverter\nfrom dotenv import load_dotenv, find_dotenv\n\n@pytest.fixture(scope=\"module\")\ndef test_rapid_api_key():\n    load_dotenv(find_dotenv())\n    if \"RAPID_API_KEY\" not in os.environ or not os.environ[\"RAPID_API_KEY\"]:\n        with pytest.raises(ValueError):\n            CurrencyConverter()\n        pytest.skip(\"Rapid api key is not set.\")\n    else:\n        return True\n\n@pytest.mark.usefixtures(\"test_rapid_api_key\")\ndef test_currency_converter_api():\n    load_dotenv(find_dotenv())\n    currency_converter_api = CurrencyConverter()\n    params = {\n        \"from\": \"USD\",\n        \"to\": \"EUR\",\n        \"amount\": 2\n    }\n    result = currency_converter_api.run(params=params)\n    print(result)\n    assert isinstance(result, str)\n"
  },
  {
    "path": "tests/test_tools/test_top_series.py",
    "content": "import os\nimport pytest\nimport requests\nfrom requests.models import Response\nimport json\n\nfrom pyopenagi.tools.imdb.top_series import TopSeries\nfrom dotenv import load_dotenv, find_dotenv\n\n@pytest.fixture(scope=\"module\")\ndef test_rapid_api_key():\n    load_dotenv(find_dotenv())\n    if \"RAPID_API_KEY\" not in os.environ or not os.environ[\"RAPID_API_KEY\"]:\n        with pytest.raises(ValueError):\n            TopSeries()\n        pytest.skip(\"RAPID api key is not set.\")\n    else:\n        return True\n\nclass ImdbTopSeriesMock:\n    @staticmethod\n    def json():\n        mock_items = []\n        mock_title = \"Mock Title\"\n        mock_description = \"Mock Description.\"\n        mock_image = \"https://m.media-amazon.com/images/Mock/Standard.Image.jpg\"\n        mock_big_image = \"https://m.media-amazon.com/images/Mock/Big.Image.jpg\"\n        mock_genre = [\"Drama\", \"Fantasy\"]\n        mock_thumbnail = \"https://m.media-amazon.com/images/Mock/Thumb.Image.jpg\"\n        mock_rating = 9.2\n        mock_year = \"2011-2019\"\n        mock_imdbid = \"tt0000000\"\n        mock_imdb_link = \"https://www.imdb.com/title/tt0000000\"\n\n        for i in range(100):\n            mock_items.append(\n                {\n                    \"rank\": i + 1,\n                    \"title\": mock_title,\n                    \"description\": mock_description,\n                    \"image\": mock_image,\n                    \"big_image\": mock_big_image,\n                    \"genre\": mock_genre,\n                    \"thumbnail\": mock_thumbnail,\n                    \"rating\": mock_rating,\n                    \"id\": f\"top{i+1}\",\n                    \"year\": mock_year,\n                    \"imdbid\": mock_imdbid,\n                    \"mock_imdb_link\": mock_imdb_link,\n                }\n            )\n        mock_response = Response()\n        mock_response.status_code = 200\n        mock_response._content = str.encode(json.dumps(mock_items))\n        return mock_response.json()\n\n\n@pytest.fixture(autouse=True)\ndef mock_response(monkeypatch):\n    def mock_get(*args, **kwargs):\n        return ImdbTopSeriesMock()\n\n    monkeypatch.setattr(requests, \"get\", mock_get)\n\n\n@pytest.mark.usefixtures(\"test_rapid_api_key\")\n@pytest.mark.parametrize(\n    \"valid_start, valid_end\",\n    [\n        [1, 100],\n        [60, 61],\n        [60, 62],\n    ],\n)\ndef test_top_series_api_valid_input_outputs_valid_delimiter_count(\n    valid_start, valid_end\n):\n    load_dotenv(find_dotenv())\n    top_series_api = TopSeries()\n    params = {\"start\": valid_start, \"end\": valid_end}\n    result = top_series_api.run(params=params)\n    assert isinstance(result, str)\n    assert result.count(\";\") == max(0, int(valid_end) - int(valid_start))\n\n@pytest.mark.usefixtures(\"test_rapid_api_key\")\ndef test_top_series_api_reverse_range_returns_blank():\n    load_dotenv(find_dotenv())\n    top_series_api = TopSeries()\n    params = {\"start\": 100, \"end\": 0}\n    result = top_series_api.run(params=params)\n    assert result == \"Top 100-0 series ranked by IMDB are: \"\n\n\n@pytest.mark.parametrize(\n    \"invalid_start, valid_end\",\n    [\n        [\"0\", 100],\n        [0.5, 100],\n        [[], 100],\n        [{}, 100]\n    ]\n)\n@pytest.mark.usefixtures(\"test_rapid_api_key\")\ndef test_top_series_api_invalid_start_type_raises_typeerror(invalid_start, valid_end):\n    load_dotenv(find_dotenv())\n    top_series_api = TopSeries()\n    params = {\"start\": invalid_start, \"end\": valid_end}\n    with pytest.raises(TypeError):\n        top_series_api.run(params=params)\n\n\n@pytest.mark.parametrize(\n    \"invalid_start, valid_end\",\n    [\n        [1, \"0\"],\n        [1, 0.5],\n        [1, []],\n        [1, {}]\n    ]\n)\n@pytest.mark.usefixtures(\"test_rapid_api_key\")\ndef test_top_series_api_invalid_end_type_raises_typeerror(invalid_start, valid_end):\n    load_dotenv(find_dotenv())\n    top_series_api = TopSeries()\n    params = {\"start\": invalid_start, \"end\": valid_end}\n    with pytest.raises(TypeError):\n        top_series_api.run(params=params)\n\n@pytest.mark.usefixtures(\"test_rapid_api_key\")\ndef test_top_series_api_invalid_start_count_raises_indexerror():\n    load_dotenv(find_dotenv())\n    top_series_api = TopSeries()\n    invalid_start = {\"start\": 101, \"end\": 102}\n    with pytest.raises(IndexError):\n        top_series_api.run(params=invalid_start)\n\n@pytest.mark.usefixtures(\"test_rapid_api_key\")\ndef test_top_series_api_invalid_end_count_raises_indexerror():\n    load_dotenv(find_dotenv())\n    top_series_api = TopSeries()\n    invalid_end = {\"start\": 1, \"end\": 101}\n    with pytest.raises(IndexError):\n        top_series_api.run(params=invalid_end)\n"
  },
  {
    "path": "tests/test_tools/test_wolfram_alpha.py",
    "content": "import os\nimport pytest\n\nfrom pyopenagi.tools.wolfram.wolfram_alpha import WolframAlpha\nfrom dotenv import load_dotenv, find_dotenv\n\n@pytest.fixture(scope=\"module\")\ndef test_wolfram_alpha_id():\n    load_dotenv(find_dotenv())\n    if \"WOLFRAM_ALPHA_APPID\" not in os.environ or not os.environ[\"WOLFRAM_ALPHA_APPID\"]:\n        with pytest.raises(ValueError):\n            WolframAlpha()\n        pytest.skip(\"WolframAlpha app id is not set.\")\n    else:\n        return True\n\n@pytest.mark.usefixtures(\"test_wolfram_alpha_id\")\ndef test_wolfram_alpha():\n    wolfram_alpha = WolframAlpha()\n    query = \"What is the square root of 144?\"\n    result = wolfram_alpha.run(query)\n    assert \"12\" in result\n"
  },
  {
    "path": "tests/test_tools/test_words_api.py",
    "content": "import os\nimport pytest\n\nfrom pyopenagi.tools.words_api.words_api import WordsAPI\nfrom dotenv import load_dotenv, find_dotenv\n\n@pytest.fixture(scope=\"module\")\ndef test_rapid_api_key():\n    load_dotenv(find_dotenv())\n    if \"RAPID_API_KEY\" not in os.environ or not os.environ[\"RAPID_API_KEY\"]:\n        with pytest.raises(ValueError):\n            WordsAPI()\n        pytest.skip(\"Rapid api key is not set.\")\n\n@pytest.mark.usefixtures(\"test_rapid_api_key\")\ndef test_words_api():\n    words_api = WordsAPI()\n    params = {\n        \"word\": \"look\",\n        \"api_name\": \"typeOf\",\n    }\n    result = words_api.run(params=params)\n    print(result)\n    assert isinstance(result, str)\n"
  },
  {
    "path": "tools.md",
    "content": "# Tool Configuration\n## Available tools\n\n### Wolfram Alpha\n1. Register wolfram alpha app account and activate [APP ID](https://developer.wolframalpha.com/access)  \n2. Setup Wolfram Alpha APP_ID\n```bash\nexport WOLFRAM_ALPHA_APPID=<YOUR_APP_ID>\n```\n\n### Rapid API Tool\n1. Register for [Rapid API](https://rapidapi.com/hub)\n2. Click into the tool page that you want to call and click the (`Subscribe to Test`) button to activate tools.\n3. Setup up Rapid API Key\n```bash\nexport RAPID_API_KEY=<YOUR_RAPID_API_KEY>\n```\n#### Current supported Rapid API tools\n- [Words API](https://rapidapi.com/dpventures/api/wordsapi/)\n- [Moon Phase](https://rapidapi.com/MoonAPIcom/api/moon-phase/)\n- [Trip Advisor](https://rapidapi.com/DataCrawler/api/tripadvisor16)\n- [Shazam](https://rapidapi.com/apidojo/api/shazam/)\n- [IMDB](https://rapidapi.com/rapihub-rapihub-default/api/imdb-top-100-movies/)\n\n\n"
  }
]