Repository: agiresearch/OpenAGI Branch: main Commit: 26c119e55b8d Files: 179 Total size: 488.7 KB Directory structure: gitextract_5k2uygq5/ ├── .github/ │ ├── ISSUE_TEMPLATE/ │ │ ├── 001-report-bug.yml │ │ ├── 002-feature-request.yml │ │ └── 003-misc-discussion.yml │ ├── PULL_REQUEST_TEMPLATE.md │ └── workflows/ │ ├── ci.yml │ └── publish.yml ├── .gitignore ├── .pre-commit-config.yaml ├── CONTRIBUTE.md ├── LICENSE ├── README.md ├── pyopenagi/ │ ├── README.md │ ├── __init__.py │ ├── agents/ │ │ ├── README.md │ │ ├── __init__.py │ │ ├── agent_factory.py │ │ ├── agent_process.py │ │ ├── base_agent.py │ │ ├── call_core.py │ │ ├── example/ │ │ │ ├── README.md │ │ │ ├── academic_agent/ │ │ │ │ ├── agent.py │ │ │ │ ├── config.json │ │ │ │ └── meta_requirements.txt │ │ │ ├── cocktail_mixlogist/ │ │ │ │ ├── agent.py │ │ │ │ ├── config.json │ │ │ │ └── meta_requirements.txt │ │ │ ├── cook_therapist/ │ │ │ │ ├── agent.py │ │ │ │ ├── config.json │ │ │ │ └── meta_requirements.txt │ │ │ ├── creation_agent/ │ │ │ │ ├── agent.py │ │ │ │ ├── config.json │ │ │ │ └── meta_requirements.txt │ │ │ ├── fashion_stylist/ │ │ │ │ ├── agent.py │ │ │ │ ├── config.json │ │ │ │ └── meta_requirements.txt │ │ │ ├── festival_card_designer/ │ │ │ │ ├── agent.py │ │ │ │ ├── config.json │ │ │ │ └── meta_requirements.txt │ │ │ ├── fitness_trainer/ │ │ │ │ ├── agent.py │ │ │ │ ├── config.json │ │ │ │ └── meta_requirements.txt │ │ │ ├── game_agent/ │ │ │ │ ├── agent.py │ │ │ │ ├── config.json │ │ │ │ └── meta_requirements.txt │ │ │ ├── interior_decorator/ │ │ │ │ ├── agent.py │ │ │ │ ├── config.json │ │ │ │ └── meta_requirements.txt │ │ │ ├── language_tutor/ │ │ │ │ ├── agent.py │ │ │ │ ├── config.json │ │ │ │ └── meta_requirements.txt │ │ │ ├── logo_creator/ │ │ │ │ ├── agent.py │ │ │ │ ├── config.json │ │ │ │ └── meta_requirements.txt │ │ │ ├── math_agent/ │ │ │ │ ├── agent.py │ │ │ │ ├── config.json │ │ │ │ └── meta_requirements.txt │ │ │ ├── meme_creator/ │ │ │ │ ├── agent.py │ │ │ │ ├── config.json │ │ │ │ └── meta_requirements.txt │ │ │ ├── music_composer/ │ │ │ │ ├── agent.py │ │ │ │ ├── config.json │ │ │ │ └── meta_requirements.txt │ │ │ ├── plant_care_assistant/ │ │ │ │ ├── agent.py │ │ │ │ ├── config.json │ │ │ │ └── meta_requirements.txt │ │ │ ├── rag_agent/ │ │ │ │ ├── README.md │ │ │ │ ├── agent.py │ │ │ │ ├── config.json │ │ │ │ ├── data/ │ │ │ │ │ └── paul_graham/ │ │ │ │ │ └── paul_graham_essay.txt │ │ │ │ └── meta_requirements.txt │ │ │ ├── rec_agent/ │ │ │ │ ├── agent.py │ │ │ │ ├── config.json │ │ │ │ └── meta_requirements.txt │ │ │ ├── story_teller/ │ │ │ │ ├── agent.py │ │ │ │ ├── config.json │ │ │ │ └── meta_requirements.txt │ │ │ ├── tech_support_agent/ │ │ │ │ ├── agent.py │ │ │ │ ├── config.json │ │ │ │ └── meta_requirements.txt │ │ │ ├── transcribe_agent/ │ │ │ │ ├── agent.py │ │ │ │ ├── config.json │ │ │ │ └── meta_requirements.txt │ │ │ ├── travel_agent/ │ │ │ │ ├── agent.py │ │ │ │ ├── config.json │ │ │ │ └── meta_requirements.txt │ │ │ └── travel_planner_agent/ │ │ │ ├── README.md │ │ │ ├── agent.py │ │ │ ├── config.json │ │ │ ├── meta_requirements.txt │ │ │ └── prompts.py │ │ ├── interact.py │ │ ├── om-raheja/ │ │ │ └── transcribe_agent/ │ │ │ ├── agent.py │ │ │ ├── config.json │ │ │ └── meta_requirements.txt │ │ └── react_agent.py │ ├── data/ │ │ └── agent_tasks/ │ │ ├── README.md │ │ └── example/ │ │ ├── academic_agent_task.txt │ │ ├── cocktail_mixlogist_task.txt │ │ ├── cook_therapist_task.txt │ │ ├── creation_agent_task.txt │ │ ├── fashion_stylist_task.txt │ │ ├── festival_card_designer_task.txt │ │ ├── fitness_trainer_task.txt │ │ ├── game_agent_task.txt │ │ ├── interior_decorator_task.txt │ │ ├── language_tutor_task.txt │ │ ├── logo_creator_task.txt │ │ ├── math_agent_task.txt │ │ ├── meme_creator_task.txt │ │ ├── music_composer_task.txt │ │ ├── plant_care_assistant_task.txt │ │ ├── rec_agent_task.txt │ │ ├── story_teller_task.txt │ │ ├── tech_support_agent_task.txt │ │ ├── travel_agent_task.txt │ │ └── travel_planner_agent_task.txt │ ├── manager/ │ │ └── manager.py │ ├── queues/ │ │ ├── README.md │ │ ├── base_queue.py │ │ └── llm_request_queue.py │ ├── tools/ │ │ ├── README.md │ │ ├── __init__.py │ │ ├── arxiv/ │ │ │ └── arxiv.py │ │ ├── base.py │ │ ├── bing/ │ │ │ └── bing_search.py │ │ ├── currency_converter/ │ │ │ └── currency_converter.py │ │ ├── google/ │ │ │ ├── google_places.py │ │ │ └── google_search.py │ │ ├── imdb/ │ │ │ ├── top_movie.py │ │ │ ├── top_movies.py │ │ │ └── top_series.py │ │ ├── impira/ │ │ │ └── doc_question_answering.py │ │ ├── meteosource_weather/ │ │ │ └── find_place.py │ │ ├── moonphase/ │ │ │ └── moon_phase_search.py │ │ ├── openai/ │ │ │ └── speech_to_text.py │ │ ├── shazam/ │ │ │ └── song_auto_complete.py │ │ ├── stability-ai/ │ │ │ ├── sdxl_turbo.py │ │ │ └── text_to_image.py │ │ ├── suno/ │ │ │ └── text_to_speech.py │ │ ├── timbrooks/ │ │ │ └── image_to_image.py │ │ ├── transcriber/ │ │ │ └── transcriber.py │ │ ├── travel_planner/ │ │ │ ├── accommodations.py │ │ │ ├── attractions.py │ │ │ ├── cities.py │ │ │ ├── flights.py │ │ │ ├── google_distance_matrix.py │ │ │ ├── notebook.py │ │ │ ├── planner.py │ │ │ └── restaurants.py │ │ ├── trip_advisor/ │ │ │ ├── airport_search.py │ │ │ ├── flight_search.py │ │ │ ├── get_hotel_details.py │ │ │ ├── get_restaurant_details.py │ │ │ ├── hotel_location_search.py │ │ │ ├── hotel_search.py │ │ │ ├── restaurant_location_search.py │ │ │ └── restaurant_search.py │ │ ├── wikipedia/ │ │ │ └── wikipedia.py │ │ ├── wolfram/ │ │ │ └── wolfram_alpha.py │ │ └── words_api/ │ │ └── words_api.py │ └── utils/ │ ├── README.md │ ├── __init__.py │ ├── chat_template.py │ ├── commands/ │ │ └── top.py │ ├── compressor.py │ ├── logger.py │ └── utils.py ├── pyproject.toml ├── requirements-dev.txt ├── requirements.txt ├── tests/ │ ├── README.md │ ├── __init__.py │ ├── test_agent_creation.py │ └── test_tools/ │ ├── README.md │ ├── test_currency_converter.py │ ├── test_top_series.py │ ├── test_wolfram_alpha.py │ └── test_words_api.py └── tools.md ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/ISSUE_TEMPLATE/001-report-bug.yml ================================================ name: Bug report description: Raise an issue here if you find a bug. title: "[Bug] " labels: ["bug"] body: - type: checkboxes attributes: label: Checked other resources description: Please confirm and check all the following options. options: - label: I added a very descriptive title to this issue. required: true - label: I am sure the issue hasn't been already addressed by searching through https://github.com/agiresearch/OpenAGI/issues. required: true - label: The usage issue is not resolved by updating to the latest stable version in the main branch. required: true validations: required: true - type: textarea attributes: label: Describe your current environment description: | Your current environment information (including OS, GPU, Cuda-version) - type: textarea attributes: label: Describe the bug description: | Please provide a clear and concise description of what the bug is. If relevant, add a minimal example so that we can reproduce the error by running the code. validations: required: true - type: markdown attributes: value: > Thanks for contributing 🎉! ================================================ FILE: .github/ISSUE_TEMPLATE/002-feature-request.yml ================================================ name: Feature request description: Submit a proposal/request for a new aios feature title: "[Feature] " labels: ["feature request"] body: - type: checkboxes attributes: label: Checked other resources description: Please confirm and check all the following options. options: - label: I added a very descriptive title to this issue. required: true - label: I am sure the issue hasn't been already addressed by searching through https://github.com/agiresearch/OpenAGI/issues. required: true - type: textarea attributes: label: The feature, motivation and pitch description: > 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. validations: required: true - type: textarea attributes: label: Alternatives description: > A description of any alternative solutions or features you've considered, if any. - type: textarea attributes: label: Additional context description: > Add any other context or screenshots about the feature request. - type: markdown attributes: value: > Thanks for contributing 🎉! ================================================ FILE: .github/ISSUE_TEMPLATE/003-misc-discussion.yml ================================================ name: Misc/random discussions that do not fit into the above categories. description: Submit a discussion as you like. Note that developers are heavily overloaded and we mainly rely on community users to answer these issues. title: "[Misc] " labels: ["misc discussion"] body: - type: textarea attributes: label: Anything you want to discuss about aios. description: > Anything you want to discuss about aios. validations: required: true - type: markdown attributes: value: > Thanks for contributing 🎉! ================================================ FILE: .github/PULL_REQUEST_TEMPLATE.md ================================================ Thank you for your contribution to OpenAGI! Before submitting the pull request, please ensure **the PR meets the following criteria**! This helps improve the efficiency of the review process. ### Code Quality Before submitting your PR, you need to follow the steps below to maintain code quality. - Use `pip install -r requirements-dev.txt` to install the extra dependencies in requirements-dev.txt for the following checks. - 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. - Use `pytest -v tests/` to run the test code and make sure it passes all the checks. ### PR title and classification Only 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: - `feat` Add new features - `fix` Fix bugs - `docs` Modify documents like README, CONTRIBUTE - `style` Modify code format like space and comma without changing code logic - `refactor` Refactor code structure without adding new features or fixing new bugs - `perf` Improve performance or user experience - `test` Test features, including unit test and integration test - `chore` Change the build procedure or add dependencies - `revert` Revert to the previous version ### PR messages - **Description:** a description of the change - **Issue:** the issue # it fixes, if applicable - **Dependencies:** any dependencies required for this change ### For the Reviews - 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. - 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). ================================================ FILE: .github/workflows/ci.yml ================================================ name: CI on: [push,pull_request] jobs: run-pytest: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Set up Python uses: actions/setup-python@v2 with: python-version: "3.11" - name: Install dependencies run: | python -m pip install --upgrade pip pip install -r requirements-dev.txt - name: Run tests run: | pytest -v tests ================================================ FILE: .github/workflows/publish.yml ================================================ name: Publish Python Package on: push: tags: - "v*" jobs: deploy: runs-on: ubuntu-latest environment: release permissions: id-token: write steps: - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v4 with: python-version: "3.11" cache: "pip" - name: Install dependencies run: | python -m pip install --upgrade pip pip install hatch - name: Build package run: hatch build - name: Publish package distributions to PyPI uses: pypa/gh-action-pypi-publish@release/v1 ================================================ FILE: .gitignore ================================================ .idea/ .vscode/ .DS_Store # Ignore Python compiled files __pycache__/ *.py[cod] # Ignore Mac system files .DS_Store # Ignore package info *.egg-info/ *.ipynb api_key.py generated_images/ generated_poems/ generated_music/ ./UI/.env*.local .env chroma_db/ dist/ /dist/ dist ================================================ FILE: .pre-commit-config.yaml ================================================ repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v3.2.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer - id: check-yaml - id: check-added-large-files ================================================ FILE: CONTRIBUTE.md ================================================ # How to contribute to OpenAGI Thank you for your interest in OpenAGI! Here's a guide to help you contribute to this project. ## 1. Get Started ### Fork the repository At first, you need to fork this copy and create your own version of repo. ### Clone the repository and install the dependencies. ### Installing dependencies with pip ```bash pip install -r requirements.txt ``` ### Installing pre-commit We strongly recommend installing [pre-commit](https://pre-commit.com/) to ensure proper formatting during development ## 2. Developing and Testing ### Create a branch Create a new branch for developing your creative features ```shell git checkout -b your-feature ``` ### Make changes and testing You 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. ### Run tests Add your test code into the `openagi/tests/` directory if any, then run test via [pytest](https://docs.pytest.org/en/8.0.x/) ``` cd openagi pytest -v tests ``` sample output ``` ============================================================================================================================= test session starts ============================================================================================================================== platform darwin -- Python 3.11.9, pytest-8.1.1, pluggy-1.5.0 -- "" cachedir: .pytest_cache rootdir: "" plugins: anyio-4.3.0 collected 2 items tests/test_agent_creation.py::test_agent_creation PASSED [ 50%] tests/test_tools.py::test_currency_converter_api PASSED [100%] ``` ## 3. Submitting Changes ### Code format check Please ensure your code is formatted correctly using pre-commit ### Git commit message We strongly recommend your git commit follows the format below ```bash git commit -m : ``` | | | |-------------|--------------------------------------------------| | `feat` | Add new features | | `fix` | Fix bugs | | `docs` | Modify documents like README, CONTRIBUTE | | `style` | Modify code format like space and comma without changing code logic | | `refactor` | Refactor code structure without adding new features or fixing new bugs | | `perf` | Improve performance or user experience | | `test` | Test features, including unit test and integration test | | `chore` | Change the build procedure or add dependencies | | `revert` | Revert to the previous version | 💡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). ### Create a Pull Request 1. 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. 2. 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. 3. 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. ## 4. Review and Approval Our 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! ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2024 AGI Research Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # OpenAGI: Package for AI Agent Creation [![Code License](https://img.shields.io/badge/Code%20License-MIT-green.svg)](https://github.com/agiresearch/OpenAGI/blob/main/LICENSE) ## ✈️ Getting Started OpenAGI is used as the agent creation package to build agents for [AIOS](https://github.com/agiresearch/AIOS). **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. ### Installation From PyPI ``` pip install pyopenagi ``` Locally ``` git clone https://agiresearch/OpenAGI cd OpenAGI pip install -e . ``` ### Usage #### Add a new agent To add a new agent, first you need to create a folder under the pyopenagi/agents folder. The folder needs to be the following structure: ``` - pyopenagi/agents - author - agent_name - agent.py # main code for the agent execution logic - config.json # set up configurations for agent - meta_requirements.txt # dependencies that the agent needs ``` If 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). If you want to add new tools for your developing agent, you need to add a new tool file in the [folder](./pyopenagi/tools/). #### Upload agent If you have developed and tested your agent, and you would like to share your agents, you can use the following to upload your agents ``` python pyopenagi/agents/interact.py --mode upload --agent ``` 💡Note that the `agent` param must exactly match the folder you put your agent locally. #### Download agent If you want to look at implementations of other agents that others have developed, you can use the following command: ``` python pyopenagi/agents/interact.py --mode download --agent ``` ## 🚀 Contributions For 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! ## 🖋️ Research Please 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). ``` @article{openagi, title={OpenAGI: When LLM Meets Domain Experts}, author={Ge, Yingqiang and Hua, Wenyue and Mei, Kai and Ji, Jianchao and Tan, Juntao and Xu, Shuyuan and Li, Zelong and Zhang, Yongfeng}, journal={In Advances in Neural Information Processing Systems (NeurIPS)}, year={2023} } ``` ## 🌍 OpenAGI Contributors [![OpenAGI contributors](https://contrib.rocks/image?repo=agiresearch/OpenAGI&max=300)](https://github.com/agiresearch/OpenAGI/graphs/contributors) ## 🌟 Star History [![Star History Chart](https://api.star-history.com/svg?repos=agiresearch/OpenAGI&type=Date)](https://star-history.com/#agiresearch/OpenAGI&Date) ================================================ FILE: pyopenagi/README.md ================================================ # pyopenagi The internal implementation for OpenAGI. 1. `agents/` contains the agent implementation all future agents have to follow. 2. `queues/` contains the class implementation for queues. 3. `utils/` contains some helpful internal utilities. 4. `tools/` contains the tools the agents can use. ================================================ FILE: pyopenagi/__init__.py ================================================ ================================================ FILE: pyopenagi/agents/README.md ================================================ # pyopenagi/agents This 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` In `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. ================================================ FILE: pyopenagi/agents/__init__.py ================================================ ================================================ FILE: pyopenagi/agents/agent_factory.py ================================================ from threading import Lock from pympler import asizeof from .interact import Interactor import os import importlib import random class AgentFactory: def __init__(self, # agent_process_queue, agent_process_factory, agent_log_mode ): # self.max_aid = 256 # self.llm = llm # self.aid_pool = [i for i in range(self.max_aid)] # heapq.heapify(self.aid_pool) # self.agent_process_queue = agent_process_queue self.agent_process_factory = agent_process_factory self.current_agents = {} self.current_agents_lock = Lock() # self.terminate_signal = Event() self.agent_log_mode = agent_log_mode def snake_to_camel(self, snake_str): components = snake_str.split('_') return ''.join(x.title() for x in components) def list_agents(self): agent_list = Interactor().list_available_agents() for agent in agent_list: print(agent) def load_agent_instance(self, agent_name): # dynamically loads the module from the path author, name = agent_name.split("/") module_name = ".".join(["pyopenagi", "agents", author, name, "agent"]) class_name = self.snake_to_camel(name) agent_module = importlib.import_module(module_name) # dynamically loads the class agent_class = getattr(agent_module, class_name) return agent_class def activate_agent(self, agent_name, task_input): script_path = os.path.abspath(__file__) script_dir = os.path.dirname(script_path) # downloads the agent if its not installed already interactor = Interactor() if not os.path.exists(os.path.join(script_dir, agent_name)): interactor.download_agent(agent_name) if not interactor.check_reqs_installed(agent_name): interactor.install_agent_reqs(agent_name) # we instantiate the agent directly from the class agent_class = self.load_agent_instance(agent_name) agent = agent_class( agent_name = agent_name, task_input = task_input, agent_process_factory = self.agent_process_factory, log_mode = self.agent_log_mode ) aid = random.randint(100000, 999999) # set the identifier for the agent # aid = heapq.heappop(self.aid_pool) agent.set_aid(aid) # use a lock to make sure only one agent can read the values at a time # if not self.terminate_signal.is_set(): with self.current_agents_lock: self.current_agents[aid] = agent return agent def run_agent(self, agent_name, task_input): agent = self.activate_agent( agent_name=agent_name, task_input=task_input ) # print(task_input) output = agent.run() self.deactivate_agent(agent.get_aid()) return output def print_agent(self): headers = ["Agent ID", "Agent Name", "Created Time", "Status", "Memory Usage"] data = [] for id, agent in self.current_agents.items(): agent_name = agent.agent_name created_time = agent.created_time status = agent.status memory_usage = f"{asizeof.asizeof(agent)} bytes" data.append( [id, agent_name, created_time, status, memory_usage] ) self.print(headers=headers, data=data) def print(self, headers, data): # align output column_widths = [ max(len(str(row[i])) for row in [headers] + data) for i in range(len(headers)) ] print("+" + "-" * (sum(column_widths) + len(headers) * 3 - 3 ) + "+") print(self.format_row(headers, column_widths)) print("=" * (sum(column_widths) + len(headers) * 3 - 1)) for i, row in enumerate(data): print(self.format_row(row, column_widths)) if i < len(data): print("-" * (sum(column_widths) + len(headers) * 3 - 1)) print("+" + "-" * (sum(column_widths) + len(headers) * 3 - 3 ) + "+") def format_row(self, row, widths, align="<"): row_str = " | ".join(f"{str(item):{align}{widths[i]}}" for i, item in enumerate(row)) return row_str def deactivate_agent(self, aid): self.current_agents.pop(aid) # heapq.heappush(self.aid_pool, aid) ================================================ FILE: pyopenagi/agents/agent_process.py ================================================ from threading import Thread, Lock from ..utils.chat_template import Query import random class AgentProcess: def __init__(self, agent_name: str, query: Query ): """Agent Process Args: agent_name (str): Name of the agent query (Query): Query sent by the agent """ self.agent_name = agent_name self.query = query self.pid: int = None self.status = None self.response = None self.time_limit = None self.created_time = None self.start_time = None self.end_time = None def set_created_time(self, time): self.created_time = time def get_created_time(self): return self.created_time def set_start_time(self, time): self.start_time = time def get_start_time(self): return self.start_time def set_end_time(self, time): self.end_time = time def get_end_time(self): return self.end_time def set_priority(self, priority): self.priority = priority def get_priority(self): return self.priority def set_status(self, status): self.status = status def get_status(self): return self.status def set_pid(self, pid): self.pid = pid def get_pid(self): return self.pid def get_response(self): return self.response def set_response(self, response): self.response = response def get_time_limit(self): return self.time_limit def set_time_limit(self, time_limit): self.time_limit = time_limit class LLMRequestProcess(AgentProcess): pass class AgentProcessFactory: def __init__(self, agent_process_log_mode = None): # self.max_pid = 1024 # self.pid_pool = [i for i in range(self.max_pid)] # heapq.heapify(self.pid_pool) self.thread = Thread(target=self.deactivate_agent_process) self.current_agent_processes = dict() self.current_agent_processes_lock = Lock() # self.terminate_signal = Event() self.agent_process_log_mode = agent_process_log_mode def activate_agent_process(self, agent_name, query): # if not self.terminate_signal.is_set(): with self.current_agent_processes_lock: agent_process = AgentProcess( agent_name = agent_name, query = query ) pid = random.randint(1000000, 9999999) # pid = heapq.heappop(self.pid_pool) agent_process.set_pid(pid) agent_process.set_status("active") self.current_agent_processes[pid] = agent_process return agent_process def print_agent_process(self): headers = ["Agent Process ID", "Agent Name", "Created Time", "Status"] data = [] for id, agent_process in self.current_agent_processes.items(): agent_name = agent_process.agent_name created_time = agent_process.created_time status = agent_process.status # memory_usage = f"{asizeof.asizeof(agent)} bytes" data.append( [id, agent_name, created_time, status] ) self.print(headers=headers, data=data) def print(self, headers, data): # align output column_widths = [ max(len(str(row[i])) for row in [headers] + data) for i in range(len(headers)) ] print("+" + "-" * (sum(column_widths) + len(headers) * 3 - 3 ) + "+") print(self.format_row(headers, column_widths)) print("=" * (sum(column_widths) + len(headers) * 3 - 1)) for i, row in enumerate(data): print(self.format_row(row, column_widths)) if i < len(data): print("-" * (sum(column_widths) + len(headers) * 3 - 1)) print("+" + "-" * (sum(column_widths) + len(headers) * 3 - 3 ) + "+") def format_row(self, row, widths, align="<"): row_str = " | ".join(f"{str(item):{align}{widths[i]}}" for i, item in enumerate(row)) return row_str def deactivate_agent_process(self, pid): self.current_agent_processes.pop(pid) # heapq.heappush(self.pid_pool, pid) def start(self): """start the factory to check inactive agent""" self.thread.start() def stop(self): self.thread.join() ================================================ FILE: pyopenagi/agents/base_agent.py ================================================ import os import json from .agent_process import ( AgentProcess ) import time from threading import Thread from ..utils.logger import AgentLogger from ..utils.chat_template import Query import importlib from aios.hooks.stores._global import global_llm_req_queue_add_message class CustomizedThread(Thread): def __init__(self, target, args=()): super().__init__() self.target = target self.args = args self.result = None def run(self): self.result = self.target(*self.args) def join(self): super().join() return self.result class BaseAgent: def __init__(self, agent_name, task_input, agent_process_factory, log_mode: str ): self.agent_name = agent_name self.config = self.load_config() self.tool_names = self.config["tools"] self.agent_process_factory = agent_process_factory self.tool_list = dict() self.tools = [] self.tool_info = [] # simplified information of the tool: {"name": "xxx", "description": "xxx"} self.load_tools(self.tool_names) self.start_time = None self.end_time = None self.request_waiting_times: list = [] self.request_turnaround_times: list = [] self.task_input = task_input self.messages = [] self.workflow_mode = "manual" # (mannual, automatic) self.rounds = 0 self.log_mode = log_mode self.logger = self.setup_logger() self.logger.log("Initialized. \n", level="info") self.set_status("active") self.set_created_time(time.time()) def run(self): '''Execute each step to finish the task.''' pass # can be customization def build_system_instruction(self): pass def check_workflow(self, message): try: # print(f"Workflow message: {message}") workflow = json.loads(message) if not isinstance(workflow, list): return None for step in workflow: if "message" not in step or "tool_use" not in step: return None return workflow except json.JSONDecodeError: return None def automatic_workflow(self): for i in range(self.plan_max_fail_times): response, start_times, end_times, waiting_times, turnaround_times = self.get_response( query = Query( messages = self.messages, tools = None, message_return_type="json" ) ) if self.rounds == 0: self.set_start_time(start_times[0]) self.request_waiting_times.extend(waiting_times) self.request_turnaround_times.extend(turnaround_times) workflow = self.check_workflow(response.response_message) self.rounds += 1 if workflow: return workflow else: self.messages.append( { "role": "assistant", "content": f"Fail {i+1} times to generate a valid plan. I need to regenerate a plan" } ) return None def manual_workflow(self): pass def check_path(self, tool_calls): script_path = os.path.abspath(__file__) save_dir = os.path.join(os.path.dirname(script_path), "output") # modify the customized output path for saving outputs if not os.path.exists(save_dir): os.makedirs(save_dir) for tool_call in tool_calls: try: for k in tool_call["parameters"]: if "path" in k: path = tool_call["parameters"][k] if not path.startswith(save_dir): tool_call["parameters"][k] = os.path.join(save_dir, os.path.basename(path)) except Exception: continue return tool_calls def snake_to_camel(self, snake_str): components = snake_str.split('_') return ''.join(x.title() for x in components) def load_tools(self, tool_names): for tool_name in tool_names: org, name = tool_name.split("/") module_name = ".".join(["pyopenagi", "tools", org, name]) class_name = self.snake_to_camel(name) tool_module = importlib.import_module(module_name) tool_class = getattr(tool_module, class_name) self.tool_list[name] = tool_class() tool_format = tool_class().get_tool_call_format() self.tools.append(tool_format) self.tool_info.append( {"name": tool_format["function"]["name"], "description": tool_format["function"]["description"]} ) def pre_select_tools(self, tool_names): pre_selected_tools = [] for tool_name in tool_names: for tool in self.tools: if tool["function"]["name"] == tool_name: pre_selected_tools.append(tool) break return pre_selected_tools def setup_logger(self): logger = AgentLogger(self.agent_name, self.log_mode) return logger def load_config(self): script_path = os.path.abspath(__file__) script_dir = os.path.dirname(script_path) config_file = os.path.join(script_dir, self.agent_name, "config.json") with open(config_file, "r") as f: config = json.load(f) return config # the default method used for getting response from AIOS def get_response(self, query, temperature=0.0 ): thread = CustomizedThread(target=self.query_loop, args=(query, )) thread.start() return thread.join() def query_loop(self, query): agent_process = self.create_agent_request(query) completed_response, start_times, end_times, waiting_times, turnaround_times = "", [], [], [], [] while agent_process.get_status() != "done": thread = Thread(target=self.listen, args=(agent_process, )) current_time = time.time() # reinitialize agent status agent_process.set_created_time(current_time) agent_process.set_response(None) global_llm_req_queue_add_message(agent_process) # LLMRequestQueue.add_message(agent_process) thread.start() thread.join() completed_response = agent_process.get_response() if agent_process.get_status() != "done": self.logger.log( f"Suspended due to the reach of time limit ({agent_process.get_time_limit()}s). Current result is: {completed_response.response_message}\n", level="suspending" ) start_time = agent_process.get_start_time() end_time = agent_process.get_end_time() waiting_time = start_time - agent_process.get_created_time() turnaround_time = end_time - agent_process.get_created_time() start_times.append(start_time) end_times.append(end_time) waiting_times.append(waiting_time) turnaround_times.append(turnaround_time) # Re-start the thread if not done # self.agent_process_factory.deactivate_agent_process(agent_process.get_pid()) return completed_response, start_times, end_times, waiting_times, turnaround_times def create_agent_request(self, query): agent_process = self.agent_process_factory.activate_agent_process( agent_name = self.agent_name, query = query ) agent_process.set_created_time(time.time()) # print("Already put into the queue") return agent_process def listen(self, agent_process: AgentProcess): """Response Listener for agent Args: agent_process (AgentProcess): Listened AgentProcess Returns: str: LLM response of Agent Process """ while agent_process.get_response() is None: time.sleep(0.2) return agent_process.get_response() def set_aid(self, aid): self.aid = aid def get_aid(self): return self.aid def get_agent_name(self): return self.agent_name def set_status(self, status): """ Status type: Waiting, Running, Done, Inactive """ self.status = status def get_status(self): return self.status def set_created_time(self, time): self.created_time = time def get_created_time(self): return self.created_time def set_start_time(self, time): self.start_time = time def get_start_time(self): return self.start_time def set_end_time(self, time): self.end_time = time def get_end_time(self): return self.end_time ================================================ FILE: pyopenagi/agents/call_core.py ================================================ import time from threading import Thread from aios.hooks.stores._global import global_llm_req_queue_add_message from .agent_process import AgentProcess from ..utils.logger import AgentLogger class CustomizedThread(Thread): def __init__(self, target, args=()): super().__init__() self.target = target self.args = args self.result = None def run(self): self.result = self.target(*self.args) def join(self): super().join() return self.result class CallCore: """ Simplify BaseAgent to provide an interface for external frameworks to make LLM requests using aios. """ def __init__(self, agent_name, agent_process_factory, log_mode: str = "console" ): self.agent_name = agent_name self.agent_process_factory = agent_process_factory self.log_mode = log_mode self.logger = self.setup_logger() # the default method used for getting response from AIOS def get_response(self, query, temperature=0.0 ): thread = CustomizedThread(target=self.query_loop, args=(query,)) thread.start() return thread.join() def query_loop(self, query): agent_process = self.create_agent_request(query) completed_response, start_times, end_times, waiting_times, turnaround_times = "", [], [], [], [] while agent_process.get_status() != "done": thread = Thread(target=self.listen, args=(agent_process,)) current_time = time.time() # reinitialize agent status agent_process.set_created_time(current_time) agent_process.set_response(None) global_llm_req_queue_add_message(agent_process) # LLMRequestQueue.add_message(agent_process) thread.start() thread.join() completed_response = agent_process.get_response() if agent_process.get_status() != "done": self.logger.log( f"Suspended due to the reach of time limit ({agent_process.get_time_limit()}s). Current result is: {completed_response.response_message}\n", level="suspending" ) start_time = agent_process.get_start_time() end_time = agent_process.get_end_time() waiting_time = start_time - agent_process.get_created_time() turnaround_time = end_time - agent_process.get_created_time() start_times.append(start_time) end_times.append(end_time) waiting_times.append(waiting_time) turnaround_times.append(turnaround_time) # Re-start the thread if not done # self.agent_process_factory.deactivate_agent_process(agent_process.get_pid()) return completed_response, start_times, end_times, waiting_times, turnaround_times def create_agent_request(self, query): agent_process = self.agent_process_factory.activate_agent_process( agent_name=self.agent_name, query=query ) agent_process.set_created_time(time.time()) # print("Already put into the queue") return agent_process def listen(self, agent_process: AgentProcess): """Response Listener for agent Args: agent_process (AgentProcess): Listened AgentProcess Returns: str: LLM response of Agent Process """ while agent_process.get_response() is None: time.sleep(0.2) return agent_process.get_response() def setup_logger(self): logger = AgentLogger(self.agent_name, self.log_mode) return logger ================================================ FILE: pyopenagi/agents/example/README.md ================================================ # pyopenagi/agents/example Here are the example agents we created to demo agent creation in OpenAGI. ================================================ FILE: pyopenagi/agents/example/academic_agent/agent.py ================================================ from ...react_agent import ReactAgent import os class AcademicAgent(ReactAgent): def __init__(self, agent_name, task_input, agent_process_factory, log_mode: str): ReactAgent.__init__( self, agent_name, task_input, agent_process_factory, log_mode ) # self.workflow_mode = "manual" self.workflow_mode = "automatic" def check_path(self, tool_calls): script_path = os.path.abspath(__file__) save_dir = os.path.join( os.path.dirname(script_path), "output" ) # modify the customized output path for saving outputs if not os.path.exists(save_dir): os.makedirs(save_dir) for tool_call in tool_calls: try: for k in tool_call["parameters"]: if "path" in k: path = tool_call["parameters"][k] if not path.startswith(save_dir): tool_call["parameters"][k] = os.path.join( save_dir, os.path.basename(path) ) except Exception: continue return tool_calls def manual_workflow(self): workflow = [ {"message": "Gather research topic and keywords", "tool_use": []}, {"message": "Search for relevant papers on arXiv", "tool_use": ["arxiv"]}, {"message": "Summarize key findings of selected papers", "tool_use": []}, { "message": "Identify research gaps and generate potential research questions", "tool_use": [], }, ] return workflow def run(self): return super().run() ================================================ FILE: pyopenagi/agents/example/academic_agent/config.json ================================================ { "name": "academic_agent", "description": [ "You are an academic research assistant. ", "Help users find relevant research papers, summarize key findings, and generate potential research questions." ], "tools": [ "arxiv/arxiv" ], "meta": { "author": "example", "version": "0.0.1", "license": "CC0" }, "build": { "entry": "agent.py", "module": "AcademicAgent" } } ================================================ FILE: pyopenagi/agents/example/academic_agent/meta_requirements.txt ================================================ arxiv ================================================ FILE: pyopenagi/agents/example/cocktail_mixlogist/agent.py ================================================ from ...react_agent import ReactAgent import os class CocktailMixlogist(ReactAgent): def __init__(self, agent_name, task_input, agent_process_factory, log_mode: str ): ReactAgent.__init__(self, agent_name, task_input, agent_process_factory, log_mode) self.workflow_mode = "automatic" # self.workflow_mode = "manual" def check_path(self, tool_calls): script_path = os.path.abspath(__file__) save_dir = os.path.join(os.path.dirname(script_path), "output") # modify the customized output path for saving outputs if not os.path.exists(save_dir): os.makedirs(save_dir) for tool_call in tool_calls: try: for k in tool_call["parameters"]: if "path" in k: path = tool_call["parameters"][k] if not path.startswith(save_dir): tool_call["parameters"][k] = os.path.join(save_dir, os.path.basename(path)) except Exception: continue return tool_calls def manual_workflow(self): workflow = [ { "message": "Gather user preferences (alcoholic or non-alcoholic, taste profile, occasion)", "tool_use": [] }, { "message": "Identify available ingredients and potential substitutions", "tool_use": [] }, { "message": "Create cocktail or mocktail recipes", "tool_use": [] } ] return workflow def run(self): return super().run() ================================================ FILE: pyopenagi/agents/example/cocktail_mixlogist/config.json ================================================ { "name": "cocktail_mixlogist", "description": [ "You are a virtual mixologist. ", "Create delicious cocktails and mocktails based on user preferences, available ingredients, and dietary restrictions." ], "tools": [ "wikipedia/wikipedia" ], "meta": { "author": "example", "version": "0.0.1", "license": "CC0" } } ================================================ FILE: pyopenagi/agents/example/cocktail_mixlogist/meta_requirements.txt ================================================ ================================================ FILE: pyopenagi/agents/example/cook_therapist/agent.py ================================================ from ...react_agent import ReactAgent import os class CookTherapist(ReactAgent): def __init__(self, agent_name, task_input, agent_process_factory, log_mode: str ): ReactAgent.__init__(self, agent_name, task_input, agent_process_factory, log_mode) # self.workflow_mode = "automatic" self.workflow_mode = "manual" def check_path(self, tool_calls): script_path = os.path.abspath(__file__) save_dir = os.path.join(os.path.dirname(script_path), "output") # modify the customized output path for saving outputs if not os.path.exists(save_dir): os.makedirs(save_dir) for tool_call in tool_calls: try: for k in tool_call["parameters"]: if "path" in k: path = tool_call["parameters"][k] if not path.startswith(save_dir): tool_call["parameters"][k] = os.path.join(save_dir, os.path.basename(path)) except Exception: continue return tool_calls def manual_workflow(self): workflow = [ { "message": "Gather user input on desired ingredients, dietary restrictions, or cuisine type.", "tool_use": [] }, { "message": "Create a detailed recipe, including ingredients, measurements, and step-by-step instructions.", "tool_use": [] }, { "message": "Generate an image of the final dish.", "tool_use": ["text_to_image"] }, { "message": "Present the recipe, including image, instructions, and nutritional information.", "tool_use": [] } ] return workflow def run(self): return super().run() ================================================ FILE: pyopenagi/agents/example/cook_therapist/config.json ================================================ { "name": "cook_therapist", "description": [ "You are a culinary expert and recipe creator. ", "Your role is to generate unique and delicious recipes tailored to the user's tastes and dietary needs. " ], "tools": [ "stability-ai/text_to_image" ], "meta": { "author": "example", "version": "0.0.1", "license": "CC0" } } ================================================ FILE: pyopenagi/agents/example/cook_therapist/meta_requirements.txt ================================================ ================================================ FILE: pyopenagi/agents/example/creation_agent/agent.py ================================================ from ...react_agent import ReactAgent import os class CreationAgent(ReactAgent): def __init__(self, agent_name, task_input, agent_process_factory, log_mode: str ): ReactAgent.__init__(self, agent_name, task_input, agent_process_factory, log_mode) # self.workflow_mode = "automatic" self.workflow_mode = "manual" def check_path(self, tool_calls): script_path = os.path.abspath(__file__) save_dir = os.path.join(os.path.dirname(script_path), "output") # modify the customized output path for saving outputs if not os.path.exists(save_dir): os.makedirs(save_dir) for tool_call in tool_calls: try: for k in tool_call["parameters"]: if "path" in k: path = tool_call["parameters"][k] if not path.startswith(save_dir): tool_call["parameters"][k] = os.path.join(save_dir, os.path.basename(path)) except Exception: continue return tool_calls def manual_workflow(self): workflow = [ { "message": "Gather content requirements (platform, topic, style)", "tool_use": [] }, { "message": "Develop content concept and key messages", "tool_use": [] }, { "message": "Generate engaging text content", "tool_use": [] }, { "message": "Create visually appealing images", "tool_use": ["text_to_image"] }, { "message": "Summarize content and post", "tool_use": [] } ] return workflow def run(self): return super().run() ================================================ FILE: pyopenagi/agents/example/creation_agent/config.json ================================================ { "name": "creation_agent", "description": [ "You are a social media content creator. ", "Generate compelling text and visually appealing images" ], "tools": [ "stability-ai/text_to_image" ], "meta": { "author": "example", "version": "0.0.1", "license": "CC0" } } ================================================ FILE: pyopenagi/agents/example/creation_agent/meta_requirements.txt ================================================ diffusers==0.27.2 accelerate==0.30.1 ================================================ FILE: pyopenagi/agents/example/fashion_stylist/agent.py ================================================ from ...react_agent import ReactAgent import os class FashionStylist(ReactAgent): def __init__(self, agent_name, task_input, agent_process_factory, log_mode: str ): ReactAgent.__init__(self, agent_name, task_input, agent_process_factory, log_mode) # self.workflow_mode = "automatic" self.workflow_mode = "manual" def check_path(self, tool_calls): script_path = os.path.abspath(__file__) save_dir = os.path.join(os.path.dirname(script_path), "output") # modify the customized output path for saving outputs if not os.path.exists(save_dir): os.makedirs(save_dir) for tool_call in tool_calls: try: for k in tool_call["parameters"]: if "path" in k: path = tool_call["parameters"][k] if not path.startswith(save_dir): tool_call["parameters"][k] = os.path.join(save_dir, os.path.basename(path)) except Exception: continue return tool_calls def manual_workflow(self): workflow = [ { "message": "Gather user preferences, body type, and occasion details.", "tool_use": [] }, { "message": "Generate outfit ideas based on user input.", "tool_use": [] }, { "message": "Create visual representations of outfit ideas.", "tool_use": ["text_to_image"] }, { "message": "Analyze generated images for style coherence and alignment with user preferences.", "tool_use": ["doc_question_answering"] }, { "message": "Search for similar items online based on the generated outfit ideas.", "tool_use": ["google_search"] }, { "message": "Summarize content.", "tool_use": [] } ] return workflow def run(self): return super().run() ================================================ FILE: pyopenagi/agents/example/fashion_stylist/config.json ================================================ { "name": "fashion_stylist", "description": [ "You are a fashion designer. ", "Create custom clothing and accessory designs based on user preferences and body measurements. " ], "tools": [ "google/google_search", "stability-ai/text_to_image", "impira/doc_question_answering" ], "meta": { "author": "example", "version": "0.0.1", "license": "CC0" } } ================================================ FILE: pyopenagi/agents/example/fashion_stylist/meta_requirements.txt ================================================ soundfile wikipedia ================================================ FILE: pyopenagi/agents/example/festival_card_designer/agent.py ================================================ from ...react_agent import ReactAgent import os class FestivalCardDesigner(ReactAgent): def __init__(self, agent_name, task_input, agent_process_factory, log_mode: str ): ReactAgent.__init__(self, agent_name, task_input, agent_process_factory, log_mode) self.workflow_mode = "manual" def automatic_workflow(self): return super().automatic_workflow() def check_path(self, tool_calls): script_path = os.path.abspath(__file__) save_dir = os.path.join(os.path.dirname(script_path), "output") # modify the customized output path for saving outputs if not os.path.exists(save_dir): os.makedirs(save_dir) for tool_call in tool_calls: try: for k in tool_call["parameters"]: if "path" in k: path = tool_call["parameters"][k] if not path.startswith(save_dir): tool_call["parameters"][k] = os.path.join(save_dir, os.path.basename(path)) except Exception: continue return tool_calls def manual_workflow(self): workflow = [ { "message": "Gather user information (festival theme, target audience, card size)", "tool_use": [] }, { "message": "Identify card design elements (colors, fonts, imagery)", "tool_use": [] }, { "message": "Generate card layout options", "tool_use": ["text_to_image"] }, { "message": "Add textual elements to the festival card ", "tool_use": [] } ] return workflow def run(self): return super().run() ================================================ FILE: pyopenagi/agents/example/festival_card_designer/config.json ================================================ { "name": "festival_card_designer", "description": [ "You are a festival card designer. ", "Create unique and eye-catching festival cards based on user preferences and festival themes." ], "tools": [ "stability-ai/text_to_image" ], "meta": { "author": "example", "version": "0.0.1", "license": "CC0" } } ================================================ FILE: pyopenagi/agents/example/festival_card_designer/meta_requirements.txt ================================================ ================================================ FILE: pyopenagi/agents/example/fitness_trainer/agent.py ================================================ from ...react_agent import ReactAgent import os class FitnessTrainer(ReactAgent): def __init__(self, agent_name, task_input, agent_process_factory, log_mode: str ): ReactAgent.__init__(self, agent_name, task_input, agent_process_factory, log_mode) self.workflow_mode = "manual" def automatic_workflow(self): return super().automatic_workflow() def check_path(self, tool_calls): script_path = os.path.abspath(__file__) save_dir = os.path.join(os.path.dirname(script_path), "output") # modify the customized output path for saving outputs if not os.path.exists(save_dir): os.makedirs(save_dir) for tool_call in tool_calls: try: for k in tool_call["parameters"]: if "path" in k: path = tool_call["parameters"][k] if not path.startswith(save_dir): tool_call["parameters"][k] = os.path.join(save_dir, os.path.basename(path)) except Exception: continue return tool_calls def manual_workflow(self): workflow = [ { "message": "Gather information about the user's fitness level, goals, and any physical limitations.", "tool_use": [] }, { "message": "Create a detailed workout plan with exercise descriptions.", "tool_use": [] }, { "message": "Generate images demonstrating key exercises in the workout plan.", "tool_use": ["text_to_image"] }, { "message": "Create audio instructions for each exercise to guide the user.", "tool_use": ["text_to_speech"] }, { "message": "Compile the workout plan, images, and audio into a comprehensive fitness guide.", "tool_use": [] } ] return workflow def run(self): return super().run() ================================================ FILE: pyopenagi/agents/example/fitness_trainer/config.json ================================================ { "name": "fitness_trainer", "description": [ "You are a fitness trainer with expertise in various exercise techniques, nutrition, and personalized fitness planning. ", "Your role is to create tailored workout plans and provide clear instructions for exercises." ], "tools": [ "stability-ai/text_to_image", "suno/text_to_speech" ], "meta": { "author": "example", "version": "0.0.1", "license": "CC0" } } ================================================ FILE: pyopenagi/agents/example/fitness_trainer/meta_requirements.txt ================================================ arxiv wikipedia ================================================ FILE: pyopenagi/agents/example/game_agent/agent.py ================================================ from ...react_agent import ReactAgent class GameAgent(ReactAgent): def __init__(self, agent_name, task_input, agent_process_factory, log_mode: str ): ReactAgent.__init__(self, agent_name, task_input, agent_process_factory, log_mode) self.workflow_mode = "manual" def automatic_workflow(self): return super().automatic_workflow() def manual_workflow(self): workflow = [ { "message": "Gather user preferences (genre, platform, play style)", "tool_use": [] }, { "message": "Search for suitable games based on criteria", "tool_use": ["google_search"] }, { "message": "Provide game descriptions, ratings, and gameplay details", "tool_use": [] } ] return workflow def run(self): return super().run() ================================================ FILE: pyopenagi/agents/example/game_agent/config.json ================================================ { "name": "game_agent", "description": [ "You are a video game expert. ", "Recommend games based on user preferences, mood, and available platforms. Provide detailed game descriptions and gameplay information." ], "tools": [ "google/google_search" ], "meta": { "author": "example", "version": "0.0.1", "license": "CC0" } } ================================================ FILE: pyopenagi/agents/example/game_agent/meta_requirements.txt ================================================ arxiv wikipedia ================================================ FILE: pyopenagi/agents/example/interior_decorator/agent.py ================================================ from ...react_agent import ReactAgent import os class InteriorDecorator(ReactAgent): def __init__(self, agent_name, task_input, agent_process_factory, log_mode: str ): ReactAgent.__init__(self, agent_name, task_input, agent_process_factory, log_mode) # self.workflow_mode = "automatic" self.workflow_mode = "manual" def check_path(self, tool_calls): script_path = os.path.abspath(__file__) save_dir = os.path.join(os.path.dirname(script_path), "output") # modify the customized output path for saving outputs if not os.path.exists(save_dir): os.makedirs(save_dir) for tool_call in tool_calls: try: for k in tool_call["parameters"]: if "path" in k: path = tool_call["parameters"][k] if not path.startswith(save_dir): tool_call["parameters"][k] = os.path.join(save_dir, os.path.basename(path)) except Exception: continue return tool_calls def manual_workflow(self): workflow = [ { "message": "Gather user preferences, room dimensions, and desired style.", "tool_use": [] }, { "message": "Generate mood board images based on user input using text_to_image.", "tool_use": ["text_to_image"] }, { "message": "Analyze generated images for color schemes, furniture styles, and overall ambiance.", "tool_use": [] }, { "message": "Recommend specific furniture, decor items, and color palettes based on analysis.", "tool_use": [] } ] return workflow def run(self): return super().run() ================================================ FILE: pyopenagi/agents/example/interior_decorator/config.json ================================================ { "name": "interior_decorator", "description": [ "You are a virtual interior decorator. ", "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. " ], "tools": [ "stability-ai/text_to_image" ], "meta": { "author": "example", "version": "0.0.1", "license": "CC0" } } ================================================ FILE: pyopenagi/agents/example/interior_decorator/meta_requirements.txt ================================================ diffusers==0.27.2 accelerate==0.30.1 ================================================ FILE: pyopenagi/agents/example/language_tutor/agent.py ================================================ from ...react_agent import ReactAgent import os class LanguageTutor(ReactAgent): def __init__(self, agent_name, task_input, agent_process_factory, log_mode: str ): ReactAgent.__init__(self, agent_name, task_input, agent_process_factory, log_mode) # self.workflow_mode = "automatic" self.workflow_mode = "manual" def check_path(self, tool_calls): script_path = os.path.abspath(__file__) save_dir = os.path.join(os.path.dirname(script_path), "output") # modify the customized output path for saving outputs if not os.path.exists(save_dir): os.makedirs(save_dir) for tool_call in tool_calls: try: for k in tool_call["parameters"]: if "path" in k: path = tool_call["parameters"][k] if not path.startswith(save_dir): tool_call["parameters"][k] = os.path.join(save_dir, os.path.basename(path)) except Exception: continue return tool_calls def manual_workflow(self): workflow = [ { "message": "Identify user's target language and learning goals.", "tool_use": [] }, { "message": "Generate vocabulary lists and exercises.", "tool_use": ["google_search"] }, { "message": "Create grammar explanations and practice sentences.", "tool_use": [] }, { "message": "Provide audio examples of pronunciation.", "tool_use": ["text_to_speech"] }, { "message": "Engage in conversation practice with the user.", "tool_use": [] } ] return workflow def run(self): return super().run() ================================================ FILE: pyopenagi/agents/example/language_tutor/config.json ================================================ { "name": "language_tutor", "description": [ "You are a language tutor. You can provide vocabulary exercises, grammar explanations, and conversation practice. ", "You can also offer pronunciation guidance and cultural insights. " ], "tools": [ "google/google_search", "suno/text_to_speech" ], "meta": { "author": "example", "version": "0.0.1", "license": "CC0" } } ================================================ FILE: pyopenagi/agents/example/language_tutor/meta_requirements.txt ================================================ soundfile wikipedia ================================================ FILE: pyopenagi/agents/example/logo_creator/agent.py ================================================ from ...react_agent import ReactAgent import os class LogoCreator(ReactAgent): def __init__(self, agent_name, task_input, agent_process_factory, log_mode: str ): ReactAgent.__init__(self, agent_name, task_input, agent_process_factory, log_mode) self.workflow_mode = "manual" def check_path(self, tool_calls): script_path = os.path.abspath(__file__) save_dir = os.path.join(os.path.dirname(script_path), "output") # modify the customized output path for saving outputs if not os.path.exists(save_dir): os.makedirs(save_dir) for tool_call in tool_calls: try: for k in tool_call["parameters"]: if "path" in k: path = tool_call["parameters"][k] if not path.startswith(save_dir): tool_call["parameters"][k] = os.path.join(save_dir, os.path.basename(path)) except Exception: continue return tool_calls def automatic_workflow(self): return super().automatic_workflow() def manual_workflow(self): workflow = [ { "message": "Gather business information (name, industry, target audience)", "tool_use": [] }, { "message": "Identify brand personality and values", "tool_use": [] }, { "message": "Generate logo concepts and variations", "tool_use": ["text_to_image"] } ] return workflow def run(self): return super().run() ================================================ FILE: pyopenagi/agents/example/logo_creator/config.json ================================================ { "name": "logo_creator", "description": [ "You are a logo design expert. ", "Create unique and professional logo designs based on user-provided business information and preferences." ], "tools": [ "stability-ai/text_to_image" ], "meta": { "author": "example", "version": "0.0.1", "license": "CC0" } } ================================================ FILE: pyopenagi/agents/example/logo_creator/meta_requirements.txt ================================================ ================================================ FILE: pyopenagi/agents/example/math_agent/agent.py ================================================ from ...react_agent import ReactAgent class MathAgent(ReactAgent): def __init__(self, agent_name, task_input, agent_process_factory, log_mode: str ): ReactAgent.__init__(self, agent_name, task_input, agent_process_factory, log_mode) def automatic_workflow(self): return super().automatic_workflow() def manual_workflow(self): # TODO: add pemdas calculation support in the future workflow = [ { "message": "Identify the problem type and relevant formulas", "tool_use": ["wikipedia"] }, { "message": "Break down the problem into steps", "tool_use": [] }, { "message": "Provide final answer/solution", "tool_use": [] } ] return workflow def run(self): return super().run() ================================================ FILE: pyopenagi/agents/example/math_agent/config.json ================================================ { "name": "MathAgent", "description": [ "You are an expert who is good at solving mathematical problems. " ], "workflow": [ "identify the tool to call to do some pre-calculation. ", "perform mathematical operations using the pre-calculated result, which could involve addition, subtraction, multiplication, or division with other numeric values to solve the problem." ], "tools": ["wikipedia/wikipedia"], "meta": { "author": "example", "version": "0.0.1", "license": "CC0" } } ================================================ FILE: pyopenagi/agents/example/math_agent/meta_requirements.txt ================================================ wolframalpha wikipedia ================================================ FILE: pyopenagi/agents/example/meme_creator/agent.py ================================================ from ...react_agent import ReactAgent import os class MemeCreator(ReactAgent): def __init__(self, agent_name, task_input, agent_process_factory, log_mode: str ): ReactAgent.__init__(self, agent_name, task_input, agent_process_factory, log_mode) self.workflow_mode = "manual" def automatic_workflow(self): return super().automatic_workflow() def check_path(self, tool_calls): script_path = os.path.abspath(__file__) save_dir = os.path.join(os.path.dirname(script_path), "output") # modify the customized output path for saving outputs if not os.path.exists(save_dir): os.makedirs(save_dir) for tool_call in tool_calls: try: for k in tool_call["parameters"]: if "path" in k: path = tool_call["parameters"][k] if not path.startswith(save_dir): tool_call["parameters"][k] = os.path.join(save_dir, os.path.basename(path)) except Exception: continue return tool_calls def manual_workflow(self): workflow = [ { "message": "Gather user input (topic, text, image)", "tool_use": [] }, { "message": "Select a suitable meme template or create a custom image", "tool_use": ["text_to_image"] }, { "message": "Add text to the image based on user input", "tool_use": [] } ] return workflow def run(self): return super().run() ================================================ FILE: pyopenagi/agents/example/meme_creator/config.json ================================================ { "name": "meme_creator", "description": [ "You are a meme creator. Given a topic, text, or an image, create a funny and relevant meme." ], "tools": [ "stability-ai/text_to_image" ], "meta": { "author": "example", "version": "0.0.1", "license": "CC0" } } ================================================ FILE: pyopenagi/agents/example/meme_creator/meta_requirements.txt ================================================ arxiv wikipedia ================================================ FILE: pyopenagi/agents/example/music_composer/agent.py ================================================ from ...react_agent import ReactAgent class MusicComposer(ReactAgent): def __init__(self, agent_name, task_input, agent_process_factory, log_mode: str ): ReactAgent.__init__(self, agent_name, task_input, agent_process_factory, log_mode) # self.workflow_mode = "automatic" self.workflow_mode = "manual" def manual_workflow(self): workflow = [ { "message": "Gather user information about desired music genre, mood, and tempo.", "tool_use": [] }, { "message": "Generate basic melody, chord progression, or rhythm structure.", "tool_use": [] }, { "message": "Provide suggestions for musical development and experimentation.", "tool_use": [] }, { "message": "Convert musical elements into audio.", "tool_use": ["text_to_speech"] }, { "message": "Offer feedback on composition and suggest improvements.", "tool_use": [] } ] return workflow def run(self): return super().run() ================================================ FILE: pyopenagi/agents/example/music_composer/config.json ================================================ { "name": "music_composer", "description": [ "You are an excellent music composer. ", "Your role is to produce music based on the user's needs. " ], "tools": [ "suno/text_to_speech" ], "meta": { "author": "example", "version": "0.0.1", "license": "CC0" } } ================================================ FILE: pyopenagi/agents/example/music_composer/meta_requirements.txt ================================================ wikipedia ================================================ FILE: pyopenagi/agents/example/plant_care_assistant/agent.py ================================================ from ...react_agent import ReactAgent class PlantCareAssistant(ReactAgent): def __init__(self, agent_name, task_input, agent_process_factory, log_mode: str ): ReactAgent.__init__(self, agent_name, task_input, agent_process_factory, log_mode) self.workflow_mode = "manual" def automatic_workflow(self): return super().automatic_workflow() def manual_workflow(self): workflow = [ { "message": "Gather plant information (type, age, environment)", "tool_use": [] }, { "message": "Identify plant needs (light, water, fertilizer)", "tool_use": ["wikipedia"] }, { "message": "Create a plant care schedule", "tool_use": [] }, { "message": "Provide troubleshooting advice for plant issues", "tool_use": [] } ] return workflow def run(self): return super().run() ================================================ FILE: pyopenagi/agents/example/plant_care_assistant/config.json ================================================ { "name": "plant_care_assistant", "description": [ "You are a virtual plant expert. ", "Provide care instructions, identify plant problems, and offer reminders for plant care tasks." ], "tools": [ "wikipedia/wikipedia" ], "meta": { "author": "example", "version": "0.0.1", "license": "CC0" } } ================================================ FILE: pyopenagi/agents/example/plant_care_assistant/meta_requirements.txt ================================================ arxiv wikipedia ================================================ FILE: pyopenagi/agents/example/rag_agent/README.md ================================================ # src/agents/agent_config Each agent holds a config file in addition to the class specifying what to run. The agent config is a JSON file. Each JSON file contains the following: 1. `name` : name of the agent 2. `description` : an array with one element containing the system prompt 3. `workflow` : an array with plaintext describing what the agent will do at each iteration. this is fed into the LLM running the agent 4. `tools` : an array with complex json objects - `type` : type of tool, typically "function" - `function` : if the type of function it contains data in the specific functions. For more detailed information, cite each specific agent as an example and fit it for your purposes. ================================================ FILE: pyopenagi/agents/example/rag_agent/agent.py ================================================ from ...base_agent import BaseAgent import time import argparse from ....utils import Message from pathlib import PurePosixPath import os import chromadb from llama_index.embeddings.huggingface import HuggingFaceEmbedding from llama_index.core import VectorStoreIndex, SimpleDirectoryReader from llama_index.core import StorageContext from llama_index.core import PromptTemplate from llama_index.core.retrievers import VectorIndexRetriever from llama_index.vector_stores.chroma import ChromaVectorStore from openagi.src.agents.base import BaseAgent class RAGAgent(BaseAgent): def __init__(self, agent_name, task_input, llm, agent_process_queue, agent_process_factory, log_mode: str ): BaseAgent.__init__(self, agent_name, task_input, llm, agent_process_queue, agent_process_factory, log_mode) def run(self): request_waiting_times = [] request_turnaround_times = [] query = self.task_input self.logger.log(f"{query}\n", level="info") context = self.retrive(query) prompt = self.build_prompt(context_str=context, query_str=query) rounds = 0 response, start_times, end_times, waiting_times, turnaround_times = self.get_response( message = Message( prompt = prompt, tools = None ) ) self.set_start_time(start_times[0]) rounds += 1 request_waiting_times.extend(waiting_times) request_turnaround_times.extend(turnaround_times) response_message = response.response_message self.logger.log(f"Final result is: {response.response_message}\n", level="info") final_result = response_message self.set_status("done") self.set_end_time(time=time.time()) return { "agent_name": self.agent_name, "result": final_result, "rounds": rounds, "agent_waiting_time": self.start_time - self.created_time, "agent_turnaround_time": self.end_time - self.created_time, "request_waiting_times": request_waiting_times, "request_turnaround_times": request_turnaround_times, } def retrive(self, query: str): script_dir = os.path.dirname(os.path.realpath(__file__)) self.data_path = PurePosixPath(script_dir, "data", "paul_graham").as_posix() self.db_path = PurePosixPath(script_dir, "chroma_db").as_posix() self.collection_name = "quickstart" self.embed_model = HuggingFaceEmbedding(model_name="BAAI/bge-base-en-v1.5") self.create_db_if_not_exists() db = chromadb.PersistentClient(path=self.db_path) chroma_collection = db.get_or_create_collection(self.collection_name) vector_store = ChromaVectorStore(chroma_collection=chroma_collection) index = VectorStoreIndex.from_vector_store( vector_store, embed_model=self.embed_model, ) retriever = VectorIndexRetriever(index=index, similarity_top_k=2) retrieved_result = retriever.retrieve(query) context_str = retrieved_result[0].get_content() return context_str def create_db_if_not_exists(self): if os.path.exists(self.db_path): pass else: print("store documents to vector db!") documents = SimpleDirectoryReader(self.data_path).load_data() chroma_client = chromadb.PersistentClient(path=self.db_path) chroma_collection = chroma_client.create_collection(self.collection_name) vector_store = ChromaVectorStore(chroma_collection=chroma_collection) storage_context = StorageContext.from_defaults(vector_store=vector_store) index = VectorStoreIndex.from_documents( documents, storage_context=storage_context, embed_model=self.embed_model ) index.storage_context.persist(persist_dir=self.db_path) def build_prompt(self, context_str: str, query_str: str): prompt_template_literal = ( "{query_str}" "Use the following context as your learned knowledge, inside XML tags.\n" "\n" "{context_str}" "\n" "Avoid mentioning that you obtained the information from the context.\n" ) prompt_template = PromptTemplate(prompt_template_literal) final_prompt = prompt_template.format(context_str=context_str, query_str=query_str) return final_prompt if __name__ == "__main__": parser = argparse.ArgumentParser(description='Run RagAgent') parser.add_argument("--agent_name") parser.add_argument("--task_input") args = parser.parse_args() agent = RAGAgent(args.agent_name, args.task_input) agent.run() ================================================ FILE: pyopenagi/agents/example/rag_agent/config.json ================================================ { "name": "rag_agent", "description": [ "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." ], "workflow": [], "tool_info": [], "meta": { "author": "example", "version": "0.0.1", "license": "CC0" } } ================================================ FILE: pyopenagi/agents/example/rag_agent/data/paul_graham/paul_graham_essay.txt ================================================ What I Worked On February 2021 Before 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. The 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. The 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. I 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. With 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] The 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. Computers 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. Though 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. I 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. AI 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. There 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. For 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. I 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. I 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. I 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. What 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. So 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. Computer 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. The 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. There 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. I wanted not just to build things, but to build things that would last. In 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. And 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. I 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. That 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. So 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. I 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. Then 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." I 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. Meanwhile 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. I'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. Toward 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. Only 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] I'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. Our 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] While 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] I 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. This 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. Our 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. I 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] Interleaf 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. The 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. I 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. But 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. When 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. In 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. A 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] There 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. I 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] Asterix 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. I 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.) The 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. She 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. Meanwhile 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. If 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. Then 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. So 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. We 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. This 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. Now 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. We 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. At 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. We 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. It 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. (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.) In 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. It 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. We 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] There 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. There 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. We 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. We 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. Though 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. Another 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. Alas 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. It 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. The 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. Yahoo 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. When 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. But 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. So 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. When 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). Meanwhile 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. Around 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. I 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. Hmph. 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. By 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. I 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. Much 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. The 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. The 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] Wow, 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. This 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] In 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] I'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. I 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. One 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. It'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. Over 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. One 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. Jessica 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. When 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. One 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. So 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. Meanwhile 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. As 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] Once 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. There 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. YC 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] The 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. We'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. We 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. We 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. The 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] Fairly 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. As 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. I 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. In 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. HN 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] As 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. YC 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. There 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. One 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." At 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. In 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. I 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. When 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. She died on January 15, 2014. We knew this was coming, but it was still hard when it did. I 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.) What 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] I 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. I 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. I 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. The 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] McCarthy 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. McCarthy'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. Now 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. I 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. I 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. So 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?" Working 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. In 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. In 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. Now 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. Notes [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. [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. [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. [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. [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. [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. [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. [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. [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. [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. [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. [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. Which 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). Here'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? [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. I 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. [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. [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. [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. [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. [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. [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. But 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. Thanks to Trevor Blackwell, John Collison, Patrick Collison, Daniel Gackle, Ralph Hazell, Jessica Livingston, Robert Morris, and Harj Taggar for reading drafts of this. ================================================ FILE: pyopenagi/agents/example/rag_agent/meta_requirements.txt ================================================ langchain_core==0.2.1 llama_index==0.10.39 llama_index.embeddings.huggingface==0.2.0 llama-index-vector-stores-chroma==0.1.8 chromadb==0.5.0 ================================================ FILE: pyopenagi/agents/example/rec_agent/agent.py ================================================ from ...react_agent import ReactAgent class RecAgent(ReactAgent): def __init__(self, agent_name, task_input, agent_process_factory, log_mode ): ReactAgent.__init__(self, agent_name, task_input, agent_process_factory, log_mode) def automatic_workflow(self): return super().automatic_workflow() def manual_workflow(self): workflow = [ { "message": "identify the tool that you need to call to obtain information.", "tool_use": ["google_search"] }, { "message": "based on the information, give recommendations for the user based on the constrains. ", "tool_use": [] } ] return workflow def run(self): return super().run() ================================================ FILE: pyopenagi/agents/example/rec_agent/config.json ================================================ { "name": "RecAgent", "description": [ "You are an expert who is good at recommending TV series and movies." ], "tools": ["google/google_search"], "meta": { "author": "example", "version": "0.0.1", "license": "CC0" } } ================================================ FILE: pyopenagi/agents/example/rec_agent/meta_requirements.txt ================================================ ================================================ FILE: pyopenagi/agents/example/story_teller/agent.py ================================================ from ...react_agent import ReactAgent import os class StoryTeller(ReactAgent): def __init__(self, agent_name, task_input, agent_process_factory, log_mode: str ): ReactAgent.__init__(self, agent_name, task_input, agent_process_factory, log_mode) # self.workflow_mode = "automatic" self.workflow_mode = "manual" def manual_workflow(self): workflow = [ { "message": "Determine the story genre and theme based on user input.", "tool_use": [] }, { "message": "Generate initial story plot and characters.", "tool_use": [] }, { "message": "Create visual representations for the main character.", "tool_use": ["text_to_image"] }, { "message": "Write descriptive text for each image and analyze each image", "tool_use": ["doc_question_answering"] }, { "message": "Incorporate it into the story narrative.", "tool_use": [] } ] return workflow def check_path(self, tool_calls): script_path = os.path.abspath(__file__) save_dir = os.path.join(os.path.dirname(script_path), "output") # modify the customized output path for saving outputs if not os.path.exists(save_dir): os.makedirs(save_dir) for tool_call in tool_calls: try: for k in tool_call["parameters"]: if "path" in k: path = tool_call["parameters"][k] if not path.startswith(save_dir): tool_call["parameters"][k] = os.path.join(save_dir, os.path.basename(path)) except Exception: continue return tool_calls def run(self): return super().run() ================================================ FILE: pyopenagi/agents/example/story_teller/config.json ================================================ { "name": "story_teller", "description": [ "You are a creative storyteller. Given a genre, setting, or character, you can craft engaging narratives. ", "You can incorporate images to enhance the storytelling experience and even provide audio descriptions of scenes." ], "tools": [ "stability-ai/text_to_image", "impira/doc_question_answering" ], "meta": { "author": "example", "version": "0.0.1", "license": "CC0" } } ================================================ FILE: pyopenagi/agents/example/story_teller/meta_requirements.txt ================================================ ================================================ FILE: pyopenagi/agents/example/tech_support_agent/agent.py ================================================ from ...react_agent import ReactAgent class TechSupportAgent(ReactAgent): def __init__(self, agent_name, task_input, agent_process_factory, log_mode: str ): ReactAgent.__init__(self, agent_name, task_input, agent_process_factory, log_mode) self.workflow_mode = "manual" def automatic_workflow(self): return super().automatic_workflow() def manual_workflow(self): workflow = [ { "message": "identify the user's technical issue or requirement", "tool_use": [] }, { "message": "search for troubleshooting steps for the identified issue", "tool_use": ["google_search"] }, { "message": "organize the above information and summarize the solution", "tool_use": [] } ] return workflow def run(self): return super().run() ================================================ FILE: pyopenagi/agents/example/tech_support_agent/config.json ================================================ { "name": "tech_support_agent", "description": [ "You are an expert specialized in providing technical support, ", "including troubleshooting, software recommendations, and updates." ], "tools": [ "google/google_search" ], "meta": { "author": "example", "version": "0.0.1", "license": "CC0" } } ================================================ FILE: pyopenagi/agents/example/tech_support_agent/meta_requirements.txt ================================================ arxiv wikipedia ================================================ FILE: pyopenagi/agents/example/transcribe_agent/agent.py ================================================ from ...react_agent import ReactAgent class TranscribeAgent(ReactAgent): def __init__(self, agent_name, task_input, agent_process_factory, log_mode: str ): ReactAgent.__init__(self, agent_name, task_input, agent_process_factory, log_mode) self.workflow_mode = "manual" def manual_workflow(self): workflow = [ { "message": "figure out what to do with the audio", "tool_use": [ "transcriber/transcriber"], }, { "message": "organize the information and respond to the user", "tool_use": [ ], }, ] return workflow def run(self): return super().run() ================================================ FILE: pyopenagi/agents/example/transcribe_agent/config.json ================================================ { "name": "transcribe_agent", "description": [ "You are an agent who can transcribe audio from the microphone into text. " ], "tools": [ "transcriber/transcriber" ], "meta": { "author": "Om Raheja", "version": "0.0.1", "license": "CC0" } } ================================================ FILE: pyopenagi/agents/example/transcribe_agent/meta_requirements.txt ================================================ RealtimeSTT ================================================ FILE: pyopenagi/agents/example/travel_agent/agent.py ================================================ from ...react_agent import ReactAgent class TravelAgent(ReactAgent): def __init__(self, agent_name, task_input, agent_process_factory, log_mode: str ): ReactAgent.__init__(self, agent_name, task_input, agent_process_factory, log_mode) def automatic_workflow(self): return super().automatic_workflow() def manual_workflow(self): workflow = [ { "message": "identify the destination and search for hotel locations", "tool_use": ["hotel_location_search"] }, { "message": "based on the hotel locations, find suitable hotels using the hotel_search tool, and select the best one. ", "tool_use": None }, { "message": "get detailed information about the selected hotel", "tool_use": ["get_hotel_details"] }, { "message": ["search for the nearest airport to the origin"], "tool_use": ["airport_search"] }, { "message": ["search for the nearest airport to the destination"], "tool_use": ["airport_search"] }, { "message": ["find available flights to the destination airport using the correct date"], "tool_use": ["flight_search"] }, { "message": ["search for restaurant locations near destination"], "tool_use": ["restaurant_location_search"] }, { "message": ["based on the restaurant locations, find suitable restaurants"], "tool_use": ["restaurant_search"] }, { "message": ["get detailed information about the selected restaurants"], "tool_use": ["get_restaurant_details"] }, { "message": ["Gather additional relevant information about the destination the user is visiting"], "tool_use": ["wikipedia"] }, { "message": ["integrate the information gathered from the previous steps to provide a comprehensive travel plan"], "tool_use": None } ] return workflow def run(self): return super().run() ================================================ FILE: pyopenagi/agents/example/travel_agent/config.json ================================================ { "name": "travel_agent", "description": [ "You are an expert in planning and managing travel itineraries." ], "tools": [ "trip_advisor/" ], "meta": { "author": "example", "version": "0.0.1", "license": "CC0" } } ================================================ FILE: pyopenagi/agents/example/travel_agent/meta_requirements.txt ================================================ ================================================ FILE: pyopenagi/agents/example/travel_planner_agent/README.md ================================================ # Travel Planner Agent ## Introduction The Travel Planner Agent is replicated from the RecAgent used in the paper "TravelPlanner: A Benchmark for Real-World Planning with Language Agents". ## Start This 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`. Then submit an agent like: ```python submitAgent( agent_name="example/travel_planner_agent", 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." ) ``` Then run ```python python main.py --llm_name ``` such as ```python python main.py --llm_name gpt-4o-mini ``` [Others Guide](https://github.com/agiresearch/AIOS) ================================================ FILE: pyopenagi/agents/example/travel_planner_agent/agent.py ================================================ import re import time import os from ...react_agent import ReactAgent from ....utils.chat_template import Query from typing import List, Set from .prompts import ZEROSHOT_REACT_INSTRUCTION, PLANNER_INSTRUCTION from pandas import DataFrame actionMapping = {"FlightSearch": "flights", "AttractionSearch": "attractions", "GoogleDistanceMatrix": "google_distance_matrix", "AccommodationSearch": "accommodations", "RestaurantSearch": "restaurants", "Planner": "planner", "NotebookWrite": "notebook", "CitySearch": "cities"} INVALID_ACTION = "invalidAction" class TravelPlannerAgent(ReactAgent): """Reproduced the ReActAgent from the paper 👉 《TravelPlanner: A Benchmark for Real-World Planning with Language Agents》 """ def __init__(self, agent_name, task_input, agent_process_factory, log_mode: str, mode: str = 'zero_shot', max_rounds: int = 30, max_retries: int = 3, illegal_early_stop_patience: int = 3, city_file_path='../../../environments/travelPlanner/background/citySet.txt' ): ReactAgent.__init__(self, agent_name, task_input, agent_process_factory, log_mode) self.answer = '' self.max_rounds = max_rounds self.mode = mode self.finished = False self.current_observation = '' if self.mode == 'zero_shot': self.agent_prompt = '' self.illegal_early_stop_patience = illegal_early_stop_patience self.max_retries = max_retries self.retry_record = {key: 0 for key in self.tool_list.keys()} self.retry_record["planner"] = 0 self.retry_record[INVALID_ACTION] = 0 self.last_actions = [] self.city_set = self.load_city(city_set_path=city_file_path) def automatic_workflow(self): return super().automatic_workflow() def manual_workflow(self): return super().manual_workflow() def run(self): self.build_system_instruction() while not self.is_halted() and not self.is_finished(): # request llm for thought self.messages.append({ "role": "user", "content": f'Thought {self.rounds + 1}: ' }) response, start_times, end_times, waiting_times, turnaround_times = self.get_response( query=Query( messages=self.messages, tools=None ) ) self.request_waiting_times.extend(waiting_times) self.request_turnaround_times.extend(turnaround_times) if self.rounds == 0: self.set_start_time(start_times[0]) thought = response.response_message self.messages[-1]['content'] += thought self.logger.log(f"Thought {self.rounds + 1}: {thought}\n", level="info") # request llm for action self.messages.append({ "role": "user", "content": f'Action {self.rounds + 1}: ' }) response, start_times, end_times, waiting_times, turnaround_times = self.get_response( query=Query( messages=self.messages, tools=None ) ) self.request_waiting_times.extend(waiting_times) self.request_turnaround_times.extend(turnaround_times) action = response.response_message if action is None or action == '' or action == '\n': self.messages[-1]['content'] += """ Your action is filtered due to content. Please make sure your action does not start with ['\\n', 'Thought', 'Action', 'Observation'] and assume all the actions are permitted in this environment and take the action again.""" else: self.messages[-1]['content'] += ' ' + action self.logger.log(f"Action {self.rounds + 1}: {action}\n", level="info") if len(self.last_actions) > 0 and self.last_actions[-1] != action: self.last_actions.clear() else: self.last_actions.append(action) # examine if the same action has been repeated 3 times consecutively if len(self.last_actions) == 3: self.logger.log("The same action has been repeated 3 times consecutively. So we stop here.\n", level="info") self.finished = True return { "agent_name": self.agent_name, "result": "Failed to generate a valid plan because a deadlock.", "rounds": self.rounds, "agent_waiting_time": None, "agent_turnaround_time": None, "request_waiting_times": self.request_waiting_times, "request_turnaround_times": self.request_turnaround_times, } # request tools for observation self.messages.append({ "role": "user", "content": f'Observation {self.rounds + 1}: ' }) none_action = (action is None or action == '' or action == '\n') if none_action: self.messages[-1]['content'] += """No feedback from the environment due to the null action. Please make sure your action does not start with [Thought, Action, Observation].""" else: action_type, action_arg = parse_action(action) if action_type != "Planner": if action_type in actionMapping: pending_action = actionMapping[action_type] else: pending_action = INVALID_ACTION if self.retry_record[pending_action] + 1 > self.max_retries: action_type = "Planner" self.logger.log(f"{pending_action} early stop due to {self.max_retries} max retries.\n", "info") self.finished = True continue self.action_dispatch(action_type, action_arg) self.messages[-1]['content'] += self.current_observation if none_action: self.logger.log( f"Observation {self.rounds + 1}: No feedback from the environment due to the null action.\n") else: self.logger.log(f"Observation {self.rounds + 1}: {self.current_observation}\n", "info") if action_type and action_type == 'Planner' and self.retry_record['planner'] == 0: self.finished = True self.answer = self.current_observation continue self.rounds += 1 self.set_status("done") self.set_end_time(time=time.time()) return { "agent_name": self.agent_name, "result": self.answer, "rounds": self.rounds, "agent_waiting_time": self.start_time - self.created_time, "agent_turnaround_time": self.end_time - self.created_time, "request_waiting_times": self.request_waiting_times, "request_turnaround_times": self.request_turnaround_times, } def build_system_instruction(self): self.messages.append({ "role": "user", "content": ZEROSHOT_REACT_INSTRUCTION }) self.messages.append({ "role": "user", "content": "Query: " + self.task_input }) def build_planner_instruction(self, query: str, text: str) -> None: self.messages.clear() # simply request once self.messages.append({ "role": "user", "content": PLANNER_INSTRUCTION.format(text=text, query=query) }) def is_halted(self) -> bool: return self.rounds > self.max_rounds def is_finished(self) -> bool: return self.finished def action_dispatch(self, action_type: str, action_arg: str) -> None: """call coresponding tools by action_type Args: action_type (str): type action_arg (str): args """ if action_type == 'Planner': query = action_arg text = self.tool_list[actionMapping["NotebookWrite"]].list_all() # reset the context and build planner agent context self.build_planner_instruction(text, query) response, start_times, end_times, waiting_times, turnaround_times = self.get_response( query=Query( messages=self.messages, tools=None ) ) self.request_waiting_times.extend(waiting_times) self.request_turnaround_times.extend(turnaround_times) self.current_observation = to_string(response.response_message) self.answer = self.current_observation self.current_observation = "\n" + self.current_observation # align output self.__reset_record() elif action_type == 'NotebookWrite': try: action_name = actionMapping[action_type] self.current_observation = to_string(self.tool_list[action_name].run(self.current_data, action_arg)) self.__reset_record() except Exception as e: self.retry_record[action_name] += 1 self.current_observation = to_string(e) elif action_type in actionMapping.keys(): try: action_name = actionMapping[action_type] args = action_arg.split(', ') self.current_data = self.tool_list[action_name].run(*args) self.current_observation = to_string(self.current_data) self.__reset_record() except Exception as e: self.retry_record[action_name] += 1 self.current_observation = to_string(e) else: self.retry_record[INVALID_ACTION] += 1 self.current_observation = f'''{action_type} is Invalid Action. Valid Actions are FlightSearch[Departure City, Destination City, Date] / AccommodationSearch[City] / RestaurantSearch[City] / NotebookWrite[Short Description] / AttractionSearch[City] / CitySearch[State] / GoogleDistanceMatrix[Origin, Destination, Mode] / Planner[Query].''' def load_city(self, city_set_path: str) -> Set[str]: city_set = [] current_dir = os.path.dirname(os.path.abspath(__file__)) city_set_path = os.path.join(current_dir, city_set_path) lines = open(city_set_path, 'r').read().strip().split('\n') for unit in lines: city_set.append(unit) return set(city_set) def __reset_record(self) -> None: self.retry_record = {key: 0 for key in self.retry_record} self.retry_record[INVALID_ACTION] = 0 def parse_action(string: str): """match action type and action arg Args: string (str): string will be matched Returns: tuple[str, str]: action type and action arg """ pattern = r'^(\w+)\[(.+)\]$' match = re.match(pattern, string) try: if match: action_type = match.group(1) action_arg = match.group(2) return action_type, action_arg else: return None, None except Exception: return None, None def validate_date_format(date_list: List[str]) -> bool: for date in date_list: pattern = r'^\d{4}-\d{2}-\d{2}$' if not re.match(pattern, date): return False return True def valid_city_format(city_list: List[str], city_set: Set[str]) -> bool: return set(city_list).issubset(city_set) def to_string(data) -> str: if data is not None: if type(data) is DataFrame: return data.to_string(index=False) else: return str(data) else: return str(None) ================================================ FILE: pyopenagi/agents/example/travel_planner_agent/config.json ================================================ { "name": "travel_planner_agent", "description": [ "TravelPlanner: A Benchmark for Real-World Planning with Language Agents" ], "tools": [ "travel_planner/accommodations", "travel_planner/attractions", "travel_planner/cities", "travel_planner/flights", "travel_planner/google_distance_matrix", "travel_planner/notebook", "travel_planner/restaurants" ], "meta": { "author": "example", "version": "0.0.1", "license": "CC0" } } ================================================ FILE: pyopenagi/agents/example/travel_planner_agent/meta_requirements.txt ================================================ ================================================ FILE: pyopenagi/agents/example/travel_planner_agent/prompts.py ================================================ 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: (1) FlightSearch[Departure City, Destination City, Date]: Description: A flight information retrieval tool. Parameters: Departure City: The city you'll be flying out from. Destination City: The city you aim to reach. Date: The date of your travel in YYYY-MM-DD format. Example: FlightSearch[New York, London, 2022-10-01] would fetch flights from New York to London on October 1, 2022. (2) GoogleDistanceMatrix[Origin, Destination, Mode]: Description: Estimate the distance, time and cost between two cities. Parameters: Origin: The departure city of your journey. Destination: The destination city of your journey. Mode: The method of transportation. Choices include 'self-driving' and 'taxi'. Example: GoogleDistanceMatrix[Paris, Lyon, self-driving] would provide driving distance, time and cost between Paris and Lyon. (3) AccommodationSearch[City]: Description: Discover accommodations in your desired city. Parameter: City - The name of the city where you're seeking accommodation. Example: AccommodationSearch[Rome] would present a list of hotel rooms in Rome. (4) RestaurantSearch[City]: Description: Explore dining options in a city of your choice. Parameter: City – The name of the city where you're seeking restaurants. Example: RestaurantSearch[Tokyo] would show a curated list of restaurants in Tokyo. (5) AttractionSearch[City]: Description: Find attractions in a city of your choice. Parameter: City – The name of the city where you're seeking attractions. Example: AttractionSearch[London] would return attractions in London. (6) CitySearch[State] Description: Find cities in a state of your choice. Parameter: State – The name of the state where you're seeking cities. Example: CitySearch[California] would return cities in California. (7) NotebookWrite[Short Description] Description: 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. Parameters: 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. Example: 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. (8) Planner[Query] Description: A smart planning tool that crafts detailed plans based on user input and the information stroed in Notebook. Parameters: Query: The query from user. Example: Planner[Give me a 3-day trip plan from Seattle to New York] would return a detailed 3-day trip plan. You should use as many as possible steps to collect engough information to input to the Planner tool. Each action only calls one function once. Do not add any description in the action. Each reponse only execute one step of 'Thought', 'Action', 'Observation'. If you have a step 'Thought', don't generate 'Action'. """ 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). ***** Example ***** Query: 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? Travel Plan: Day 1: Current City: from Ithaca to Charlotte Transportation: Flight Number: F3633413, from Ithaca to Charlotte, Departure Time: 05:38, Arrival Time: 07:46 Breakfast: Nagaland's Kitchen, Charlotte Attraction: The Charlotte Museum of History, Charlotte Lunch: Cafe Maple Street, Charlotte Dinner: Bombay Vada Pav, Charlotte Accommodation: Affordable Spacious Refurbished Room in Bushwick!, Charlotte Day 2: Current City: Charlotte Transportation: - Breakfast: Olive Tree Cafe, Charlotte Attraction: The Mint Museum, Charlotte;Romare Bearden Park, Charlotte. Lunch: Birbal Ji Dhaba, Charlotte Dinner: Pind Balluchi, Charlotte Accommodation: Affordable Spacious Refurbished Room in Bushwick!, Charlotte Day 3: Current City: from Charlotte to Ithaca Transportation: Flight Number: F3786167, from Charlotte to Ithaca, Departure Time: 21:42, Arrival Time: 23:26 Breakfast: Subway, Charlotte Attraction: Books Monument, Charlotte. Lunch: Olive Tree Cafe, Charlotte Dinner: Kylin Skybar, Charlotte Accommodation: - ***** Example Ends ***** Given information: {text} Query: {query} Travel Plan:""" ================================================ FILE: pyopenagi/agents/interact.py ================================================ # executable that you can use to upload to the agent hub and download from it # we also use this to check dependencies to run agents import argparse import json import subprocess import requests import gzip import base64 import sys import os class Interactor: def __init__(self): script_path = os.path.abspath(__file__) script_dir = os.path.dirname(script_path) self.base_folder = script_dir def list_available_agents(self) -> list[dict]: """List available agents in the database""" url = "https://openagi-beta.vercel.app/api/get_all_agents" response = requests.get(url) response: dict = response.json() agent_list = [] for v in list(response.values())[:-1]: agent_list.append({ "agent": "/".join([v["author"], v["name"]]) }) return agent_list def download_agent(self, agent: str) -> None: """Download an agent from the database Args: agent (str): in the format of "author/agent_name" """ assert "/" in agent, 'agent_name should in the format of "author/agent_name"' author, name = agent.split("/") # print(author, name) query = f'https://openagi-beta.vercel.app/api/download?author={author}&name={name}' response = requests.get(query) response: dict = response.json() agent_folder = os.path.join(self.base_folder, agent) if not os.path.exists(agent_folder): os.makedirs(agent_folder) encoded_config = response.get('config') encoded_code = response.get("code") encoded_reqs = response.get('dependencies') if (encoded_config is None) or (encoded_code is None) or (encoded_reqs is None): print("Agent not found. Try uploading it first?") return self.download_config( self.decompress(encoded_config), agent ) self.download_code( self.decompress(encoded_code), agent ) self.download_reqs( self.decompress(encoded_reqs), agent ) def upload_agent(self, agent) -> None: """Upload an agent to the database Args: agent (str): in the format of "author/agent_name" """ agent_dir = os.path.join(self.base_folder, agent) author, name = agent.split("/") config_file = os.path.join(agent_dir, "config.json") with open(config_file, 'r') as f: config_data: dict[str, dict] = json.load(f) meta_data = config_data.get('meta') headers = { "Content-Type": "application/json" } # compress python code encoded_code = self.compress( self.minify_python_code(agent_dir) ) # compress meta_requirements.txt encoded_reqs = self.compress( self.minify_reqs(agent_dir) ) # compress config.json config_str = json.dumps(config_data) encoded_config = self.compress(config_str) upload_content = { 'author': author, 'name': name, 'version': meta_data.get('version'), 'license': meta_data.get('license'), 'config': encoded_config, 'code': encoded_code, 'dependencies': encoded_reqs } url = 'https://openagi-beta.vercel.app/api/upload' response = requests.post( url, data=json.dumps(upload_content), headers=headers ) if response.content: print("Uploaded successfully.") def minify_python_code(self, agent_dir): code_path = os.path.join(agent_dir, "agent.py") with open(code_path, 'r') as file: lines: list[str] = file.readlines() minified_lines = [] for line in lines: stripped_line = line.rstrip() if stripped_line and not stripped_line.lstrip().startswith("#"): minified_lines.append(stripped_line) minified_code = "\n".join(minified_lines) return minified_code def minify_reqs(self, agent_dir): req_path = os.path.join(agent_dir, "meta_requirements.txt") with open(req_path, 'r') as file: self.reqs: str = file.read() cleaned = [line.strip() for line in self.reqs.split( '\n') if line.strip() and not line.startswith('#')] minified_reqs = ';'.join(cleaned) return minified_reqs def minify_config(self, config_data): minified_config = self.compress(config_data) return minified_config def compress(self, minified_data): compressed_data = gzip.compress(minified_data.encode('utf-8')) encoded_data = base64.b64encode(compressed_data) encoded_data = encoded_data.decode('utf-8') return encoded_data def decompress(self, encoded_data): compressed_data = base64.b64decode(encoded_data) decompressed_data = gzip.decompress(compressed_data) decompressed_data = decompressed_data.decode("utf-8") decompressed_data.replace(";", "\n") return decompressed_data def download_config(self, config_data, agent) : config_path = os.path.join(self.base_folder, agent, "config.json") config_data = json.loads(config_data) with open(config_path, "w") as w: json.dump(config_data, w, indent=4) def download_reqs(self, reqs_data, agent): reqs_path = os.path.join(self.base_folder, agent, "meta_requirements.txt") reqs_data = reqs_data.replace(";", "\n") with open(reqs_path, 'w') as file: file.write(reqs_data) def download_code(self, code_data, agent): code_path = os.path.join(self.base_folder, agent, "agent.py") with open(code_path, 'w', newline='') as file: file.write(code_data) def check_reqs_installed(self, agent): # Run the `conda list` command and capture the output reqs_path = os.path.join(self.base_folder, agent, "meta_requirements.txt") try: result = subprocess.run(['conda', 'list'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) except Exception: result = subprocess.run(['pip', 'list', '--format=freeze'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) # Decode the output from bytes to string with open(reqs_path, "r") as f: reqs = [] lines = f.readlines() for line in lines: line = line.replace("\n", "") if "==" in line: reqs.append(line.split("==")[0]) else: reqs.append(line) output = result.stdout.decode('utf-8') # Extract the list of installed packages installed_packages = [line.split()[0] for line in output.splitlines() if line] # Check for each package if it is installed for req in reqs: if req not in installed_packages: return False return True def install_agent_reqs(self, agent): reqs_path = os.path.join(self.base_folder, agent, "meta_requirements.txt") with open ("deplogs.txt", "a") as f: subprocess.check_call([ sys.executable, "-m", "pip", "install", "-r", reqs_path], stdout=f, stderr=f ) print("Installing dependencies for agent: " + agent + ". Writing to deplogs.txt") def parse_args(): parser = argparse.ArgumentParser() parser.add_argument("--mode", choices=["download", "upload"]) parser.add_argument("--agent", required=True) args = parser.parse_args() return args if __name__ == '__main__': pass # list_available_agents() # list agents that can be used from db args = parse_args() mode = args.mode agent = args.agent client = Interactor() # client.check_reqs_installed(agent) # client = Interactor() if mode == "download": client.download_agent(agent) # download agents else: assert mode == "upload" client.upload_agent(agent) # upload agents ================================================ FILE: pyopenagi/agents/om-raheja/transcribe_agent/agent.py ================================================ from ...react_agent import ReactAgent class TranscribeAgent(ReactAgent): def __init__(self, agent_name, task_input, agent_process_factory, log_mode: str ): ReactAgent.__init__(self, agent_name, task_input, agent_process_factory, log_mode) self.workflow_mode = "automatic" def manual_workflow(self): pass def run(self): return super().run() ================================================ FILE: pyopenagi/agents/om-raheja/transcribe_agent/config.json ================================================ { "name": "transcribe_agent", "description": [ "You are an agent who can transcribe audio from the microphone into text. " ], "tools": [ "transcriber/transcriber" ], "meta": { "author": "Om Raheja", "version": "0.0.1", "license": "CC0" } } ================================================ FILE: pyopenagi/agents/om-raheja/transcribe_agent/meta_requirements.txt ================================================ RealtimeSTT ================================================ FILE: pyopenagi/agents/react_agent.py ================================================ from .base_agent import BaseAgent import time from ..utils.chat_template import Query import json class ReactAgent(BaseAgent): def __init__(self, agent_name, task_input, agent_process_factory, log_mode: str ): BaseAgent.__init__( self, agent_name, task_input, agent_process_factory, log_mode ) self.plan_max_fail_times = 3 self.tool_call_max_fail_times = 3 def build_system_instruction(self): prefix = "".join( [ "".join(self.config["description"]) ] ) plan_instruction = "".join( [ f'You are given the available tools from the tool list: {json.dumps(self.tool_info)} to help you solve problems. ', 'Generate a plan of steps you need to take. ', 'The plan must follow the json format as: ', '[', '{"message": "message_value1","tool_use": [tool_name1, tool_name2,...]}', '{"message": "message_value2", "tool_use": [tool_name1, tool_name2,...]}', '...', ']', 'In each step of the planned workflow, you must select the most related tool to use', 'Followings are some plan examples:', '[', '{"message": "gather information from arxiv. ", "tool_use": ["arxiv"]},', '{"message", "write a summarization based on the gathered information. ", "tool_use": []}', '];', '[', '{"message": "identify the tool that you need to call to obtain information. ", "tool_use": ["imdb_top_movies", "imdb_top_series"]},', '{"message", "give recommendations for the user based on the information. ", "tool_use": []}', '];', ] ) if self.workflow_mode == "manual": self.messages.append( {"role": "system", "content": prefix} ) else: assert self.workflow_mode == "automatic" self.messages.append( {"role": "system", "content": prefix + plan_instruction} ) def automatic_workflow(self): return super().automatic_workflow() def manual_workflow(self): pass def call_tools(self, tool_calls): # self.logger.log(f"***** It starts to call external tools *****\n", level="info") success = True actions = [] observations = [] # print(tool_calls) for tool_call in tool_calls: # print(tool_call) function_name = tool_call["name"] function_to_call = self.tool_list[function_name] function_params = tool_call["parameters"] try: function_response = function_to_call.run(function_params) actions.append(f"I will call the {function_name} with the params as {function_params}") observations.append(f"The output of calling the {function_name} tool is: {function_response}") except Exception: actions.append("I fail to call any tools.") observations.append(f"The tool parameter {function_params} is invalid.") success = False return actions, observations, success def run(self): self.build_system_instruction() task_input = self.task_input self.messages.append( {"role": "user", "content": task_input} ) self.logger.log(f"{task_input}\n", level="info") workflow = None if self.workflow_mode == "automatic": workflow = self.automatic_workflow() else: assert self.workflow_mode == "manual" workflow = self.manual_workflow() self.messages.append( {"role": "assistant", "content": f"[Thinking]: The workflow generated for the problem is {json.dumps(workflow)}"} ) self.messages.append( {"role": "user", "content": "[Thinking]: Follow the workflow to solve the problem step by step. "} ) if workflow: self.logger.log(f"Generated workflow is: {workflow}\n", level="info") else: self.logger.log(f"Fail to generate a valid workflow. Invalid JSON?\n", level="info") try: if workflow: final_result = "" for i, step in enumerate(workflow): message = step["message"] tool_use = step["tool_use"] prompt = f"At step {i + 1}, you need to: {message}. " self.messages.append({ "role": "user", "content": prompt }) if tool_use: selected_tools = self.pre_select_tools(tool_use) else: selected_tools = None response, start_times, end_times, waiting_times, turnaround_times = self.get_response( query = Query( messages = self.messages, tools = selected_tools ) ) if self.rounds == 0: self.set_start_time(start_times[0]) # execute action response_message = response.response_message tool_calls = response.tool_calls self.request_waiting_times.extend(waiting_times) self.request_turnaround_times.extend(turnaround_times) if tool_calls: for _ in range(self.plan_max_fail_times): tool_calls = self.check_path(tool_calls) actions, observations, success = self.call_tools(tool_calls=tool_calls) action_messages = "[Action]: " + ";".join(actions) observation_messages = "[Observation]: " + ";".join(observations) self.messages.append( { "role": "assistant", "content": action_messages + ". " + observation_messages } ) if success: break else: thinkings = response_message self.messages.append({ "role": "assistant", "content": thinkings }) if i == len(workflow) - 1: final_result = self.messages[-1] step_result = self.messages[-1]["content"] self.logger.log(f"At step {i + 1}, {step_result}\n", level="info") self.rounds += 1 self.set_status("done") self.set_end_time(time=time.time()) return { "agent_name": self.agent_name, "result": final_result, "rounds": self.rounds, "agent_waiting_time": self.start_time - self.created_time, "agent_turnaround_time": self.end_time - self.created_time, "request_waiting_times": self.request_waiting_times, "request_turnaround_times": self.request_turnaround_times, } else: return { "agent_name": self.agent_name, "result": "Failed to generate a valid workflow in the given times.", "rounds": self.rounds, "agent_waiting_time": None, "agent_turnaround_time": None, "request_waiting_times": self.request_waiting_times, "request_turnaround_times": self.request_turnaround_times, } except Exception as e: print(e) return {} ================================================ FILE: pyopenagi/data/agent_tasks/README.md ================================================ # Agent Tasks This 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. ================================================ FILE: pyopenagi/data/agent_tasks/example/academic_agent_task.txt ================================================ Find recent papers on the impact of social media on mental health in adolescents. Explore the potential of AI in early disease detection. Summarize key findings from studies on climate change mitigation strategies. Identify research gaps in the field of renewable energy. Find papers on the effectiveness of online education compared to traditional classrooms. Summarize key findings from studies on the impact of sleep deprivation on cognitive function. Identify research gaps in the field of human-computer interaction. Find papers on the relationship between diet and chronic diseases. Summarize key findings from studies on the effectiveness of different cancer treatments. Identify research gaps in the field of autonomous vehicles. Find papers on the impact of globalization on economic inequality. Summarize key findings from studies on the effectiveness of different teaching methods. Identify research gaps in the field of artificial intelligence ethics. Find papers on the relationship between physical activity and mental health. Summarize key findings from studies on the effectiveness of different drug delivery systems. Identify research gaps in the field of sustainable agriculture. Find papers on the impact of technology on human relationships. Summarize key findings from studies on the effectiveness of different psychotherapy techniques. Identify research gaps in the field of space exploration. Find papers on the relationship between income inequality and social unrest. Find recent papers on the use of machine learning for predicting stock market trends. Explore the potential of nanotechnology in drug delivery. Summarize key findings from studies on the impact of climate change on biodiversity. Identify research gaps in the field of quantum computing. Find papers on the effectiveness of online learning platforms for language acquisition. Summarize key findings from studies on the relationship between gut microbiota and mental health. Identify research gaps in the field of human-robot interaction. Find papers on the impact of air pollution on respiratory health. Summarize key findings from studies on the effectiveness of different diabetes management strategies. Identify research gaps in the field of renewable energy storage. Find papers on the relationship between social media use and political polarization. Summarize key findings from studies on the effectiveness of different educational interventions for children with autism. Identify research gaps in the field of cybersecurity. Find papers on the relationship between physical activity and cardiovascular health. Summarize key findings from studies on the effectiveness of different pain management techniques. Identify research gaps in the field of precision medicine. Find papers on the impact of social media on body image. Summarize key findings from studies on the effectiveness of different cognitive behavioral therapy techniques. Identify research gaps in the field of climate change adaptation. Find papers on the relationship between income inequality and health outcomes. Can AI be used to develop personalized treatment plans for cancer patients? What is the impact of climate change on agricultural yields in sub-Saharan Africa? How effective are virtual reality-based therapies for treating phobias? What are the ethical implications of using CRISPR gene editing technology? Can wearable devices be used to monitor and prevent chronic diseases? How does social media influence the spread of misinformation? What is the role of gut microbiota in the development of autoimmune diseases? Can machine learning be used to predict natural disasters? How can we improve the accessibility of mental health services for underserved populations? What are the long-term effects of screen time on children's cognitive development? Can artificial intelligence be used to develop new materials with desired properties? How can we reduce food waste and improve food security globally? What is the impact of sleep deprivation on the immune system? How can we promote sustainable consumption and production patterns? What are the challenges and opportunities of using blockchain technology in healthcare? Can virtual reality be used to improve the rehabilitation process for stroke patients? How can we address the digital divide and ensure equitable access to technology? What is the role of epigenetics in the development of complex diseases? How can we promote mental health and well-being in the workplace? What are the potential benefits and risks of using geoengineering to combat climate change? Summarize the key findings of the paper "Attention Is All You Need" by Vaswani et al. Find recent papers on the use of deep learning for image segmentation. Summarize the key findings of the paper "A Large Language Model for Code Generation" by OpenAI. Find recent papers on the impact of artificial intelligence on the job market. Find recent papers on the impact of climate change on global health. Explore the potential of AI in education. Summarize key findings from studies on the effectiveness of different dietary patterns. Identify research gaps in the field of sustainable energy. Find papers on the relationship between socioeconomic status and mental health. Summarize key findings from studies on the impact of screen time on children's development. Identify research gaps in the field of human-animal interaction. Find papers on the effectiveness of different treatments for chronic pain. Summarize key findings from studies on the impact of urbanization on biodiversity. Identify research gaps in the field of space colonization. Find recent papers on the use of machine learning for natural language processing. Explore the potential of nanotechnology in environmental remediation. Summarize key findings from studies on the impact of climate change on ocean ecosystems. Identify research gaps in the field of quantum cryptography. Find papers on the effectiveness of online learning platforms for STEM subjects. Summarize key findings from studies on the relationship between sleep deprivation and immune function. Identify research gaps in the field of human-computer collaboration. Find papers on the impact of noise pollution on cognitive function. Summarize key findings from studies on the effectiveness of different obesity treatment programs. Identify research gaps in the field of energy efficiency. Specific Research Question Requests Can AI be used to develop personalized learning experiences for students? What is the impact of deforestation on climate change? How effective are telemedicine services in rural areas? What are the ethical implications of using artificial intelligence in autonomous weapons? Can wearable devices be used to monitor and prevent falls in elderly populations? How does social media influence political participation? What is the role of gut microbiota in the development of obesity? Can machine learning be used to predict natural disasters? How can we improve access to clean water and sanitation in developing countries? What are the long-term effects of video game playing on children's cognitive development? Can artificial intelligence be used to discover new drugs? How can we reduce plastic pollution and promote circular economy? What is the impact of sleep deprivation on mental health? How can we promote sustainable tourism? What are the potential benefits and risks of using human enhancement technologies? ================================================ FILE: pyopenagi/data/agent_tasks/example/cocktail_mixlogist_task.txt ================================================ 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. Develop a non-alcoholic drink for a health-conscious brunch. Focus on fresh fruits and vegetables. Avoid added sugars and artificial sweeteners. Design a strong, smoky cocktail for a whiskey lover. Incorporate bold flavors like mezcal, chipotle, and lime. Create a festive mocktail for a children's birthday party. Use bright colors and fun garnishes. Avoid caffeine and alcohol. Develop a romantic, after-dinner drink. Focus on rich, velvety textures and sweet, indulgent flavors. Create a refreshing cocktail for a beach day. Use light, tropical flavors and incorporate coconut or pineapple. Design a low-calorie, high-protein cocktail for a fitness enthusiast. Use protein powder and natural sweeteners. Develop a sophisticated aperitif for a formal dinner party. Use classic ingredients and emphasize balance. Create a spicy margarita with a unique twist. Use fresh jalapeños or other chili peppers. Design a non-alcoholic drink inspired by Asian flavors. Use ginger, lemongrass, and other aromatic ingredients. Create a classic martini with a contemporary twist. Experiment with different vermouths and garnishes. Develop a refreshing mocktail perfect for a hot summer day. Incorporate cucumber, mint, and citrus flavors. Design a cocktail with unexpected flavor combinations. Consider using ingredients like lavender, saffron, or edible flowers. Create a festive punch for a large gathering. Focus on easy-to-make and crowd-pleasing flavors. Develop a non-alcoholic drink for a pregnant woman. Avoid alcohol and caffeine, while emphasizing flavor and refreshment. Create a cocktail inspired by a specific country or region. Use traditional ingredients and flavors. Design a mocktail that highlights seasonal fruits and vegetables. Develop a cocktail perfect for a cozy night in. Focus on warm, comforting flavors like cinnamon and nutmeg. Create a low-sugar cocktail for a diabetic guest. Use natural sweeteners and focus on flavor. Design a non-alcoholic drink with a spicy kick. Use ginger, chili peppers, or other warming spices. Create a cocktail that showcases a specific spirit or liqueur. Develop a mocktail inspired by a classic cocktail. Design a cocktail perfect for a brunch. Incorporate sparkling wine or champagne. Create a non-alcoholic drink with a creamy texture. Use coconut milk, almond milk, or other plant-based alternatives. Develop a cocktail with a balance of sweet, sour, and bitter flavors. Create a festive mocktail for New Year's Eve. Use sparkling ingredients and glamorous garnishes. Design a cocktail perfect for a bonfire. Incorporate smoky flavors and warm spices. Create a non-alcoholic drink with a strong herbal flavor. Use ingredients like rosemary, thyme, or basil. Develop a cocktail with a unique presentation. Consider using edible glassware or unusual garnishes. Create a mocktail perfect for a baby shower. Use soft, pastel colors and gentle flavors. Design a cocktail inspired by a famous painting or piece of art. Develop a non-alcoholic drink with a strong coffee flavor. Use cold brew or espresso as a base. Create a cocktail perfect for a Halloween party. Use spooky ingredients and eerie garnishes. Design a mocktail with a tropical twist. Use exotic fruits and bright colors. Develop a cocktail perfect for a sports game. Use refreshing and easy-to-drink ingredients. Create a non-alcoholic drink with a chocolatey flavor. Use cocoa powder, chocolate syrup, or chocolate-flavored ingredients. Design a cocktail perfect for a Valentine's Day date night. Use romantic ingredients and aphrodisiacs. Create a mocktail with a strong citrus flavor. Use grapefruit, lemon, or lime as the main ingredient. Develop a cocktail with a smoky flavor profile. Use mezcal, scotch, or other smoky spirits. Create a non-alcoholic drink with a floral flavor. Use rose water, elderflower, or other floral extracts. Design a cocktail perfect for a camping trip. Use simple ingredients and easy preparation methods. Create a mocktail with a strong ginger flavor. Use fresh ginger, ginger beer, or ginger syrup. Develop a cocktail with a balance of sweet and savory flavors. Create a festive mocktail for a Fourth of July celebration. Use red, white, and blue ingredients. Design a cocktail perfect for a rooftop party. Use refreshing and light ingredients. Create a non-alcoholic drink with a strong mint flavor. Use fresh mint leaves and mint syrup. Develop a cocktail with a unique presentation. Consider using edible flowers or smoke infusion. Create a mocktail perfect for a bridal shower. Use delicate flavors and elegant garnishes. Design a cocktail inspired by a classic movie or TV show. Develop a non-alcoholic drink with a strong pineapple flavor. Use fresh pineapple, pineapple juice, or pineapple puree. Create a cocktail perfect for a pool party. Use refreshing and hydrating ingredients. Design a mocktail with a strong berry flavor. Use strawberries, raspberries, or blueberries. Develop a cocktail with a balance of sweet and tart flavors. Create a festive mocktail for a St. Patrick's Day celebration. Use green ingredients and Irish whiskey flavors. Design a cocktail perfect for a wine tasting event. Use wine-based ingredients or pair the cocktail with a specific wine. Create a non-alcoholic drink with a strong coconut flavor. Use coconut milk, coconut water, or coconut cream. Develop a cocktail with a unique texture, such as frothy or creamy. Create a mocktail perfect for a baby shower. Use soft, pastel colors and gentle flavors. Design a cocktail inspired by a specific culture or cuisine. Develop a non-alcoholic drink with a strong chai flavor. Use chai tea, chai spices, or chai syrup. Create a cocktail perfect for a backyard barbecue. Use refreshing and easy-to-drink ingredients. Design a mocktail with a strong citrus flavor. Use grapefruit, lemon, or lime as the main ingredient. Develop a cocktail with a smoky flavor profile. Use mezcal, scotch, or other smoky spirits. Create a non-alcoholic drink with a floral flavor. Use rose water, elderflower, or other floral extracts. Design a cocktail perfect for a camping trip. Use simple ingredients and easy preparation methods. Create a mocktail with a strong ginger flavor. Use fresh ginger, ginger beer, or ginger syrup. Develop a cocktail with a balance of sweet and savory flavors. Create a festive mocktail for a Fourth of July celebration. Use red, white, and blue ingredients. Design a cocktail perfect for a rooftop party. Use refreshing and light ingredients. Create a non-alcoholic drink with a strong mint flavor. Use fresh mint leaves and mint syrup. Develop a cocktail with a unique presentation. Consider using edible flowers or smoke infusion. Create a mocktail perfect for a bridal shower. Use delicate flavors and elegant garnishes. Design a cocktail inspired by a classic movie or TV show. Develop a non-alcoholic drink with a strong pineapple flavor. Use fresh pineapple, pineapple juice, or pineapple puree. Create a cocktail perfect for a pool party. Use refreshing and hydrating ingredients. Design a mocktail with a strong berry flavor. Use strawberries, raspberries, or blueberries. Develop a cocktail with a balance of sweet and tart flavors. Create a festive mocktail for a St. Patrick's Day celebration. Use green ingredients and Irish whiskey flavors. Design a cocktail perfect for a wine tasting event. Use wine-based ingredients or pair the cocktail with a specific wine. Create a non-alcoholic drink with a strong coconut flavor. Use coconut milk, coconut water, or coconut cream. Develop a cocktail with a unique texture, such as frothy or creamy. Create a mocktail perfect for a baby shower. Use soft, pastel colors and gentle flavors. Design a cocktail inspired by a specific culture or cuisine. Develop a non-alcoholic drink with a strong chai flavor. Use chai tea, chai spices, or chai syrup. Create a cocktail perfect for a backyard barbecue. Use refreshing and easy-to-drink ingredients. Design a mocktail with a strong citrus flavor. Use grapefruit, lemon, or lime as the main ingredient. Develop a cocktail with a smoky flavor profile. Use mezcal, scotch, or other smoky spirits. Create a non-alcoholic drink with a floral flavor. Use rose water, elderflower, or other floral extracts. Design a cocktail perfect for a camping trip. Use simple ingredients and easy preparation methods. Create a mocktail with a strong ginger flavor. Use fresh ginger, ginger beer, or ginger syrup. Develop a cocktail with a balance of sweet and savory flavors. Create a festive mocktail for a Fourth of July celebration. Use red, white, and blue ingredients. Design a cocktail perfect for a rooftop party. Use refreshing and light ingredients. Create a non-alcoholic drink with a strong mint flavor. Use fresh mint leaves and mint syrup. Develop a cocktail with a unique presentation. Consider using edible flowers or smoke infusion. Create a mocktail perfect for a bridal shower. Use delicate flavors and elegant garnishes. Design a cocktail inspired by a classic movie or TV show. Develop a non-alcoholic drink with a strong pineapple flavor. Use fresh pineapple, pineapple juice, or pineapple puree. Create a cocktail perfect for a pool party. Use refreshing and hydrating ingredients. Design a mocktail with a strong berry flavor. Use strawberries, raspberries, or blueberries. ================================================ FILE: pyopenagi/data/agent_tasks/example/cook_therapist_task.txt ================================================ Develop a low-carb, keto-friendly dinner that is flavorful and satisfying. Create a vegetarian, Mediterranean-inspired lunch packed with nutrients. Design a gluten-free, dairy-free dessert that is rich and decadent. Develop a spicy, Thai-inspired curry with a balance of sweet, sour, and salty flavors. Create a kid-friendly, healthy snack that is high in protein and low in sugar. Design a romantic, French-inspired dinner for two with a focus on aphrodisiacs. Develop a vegan, high-protein breakfast that is quick and easy to prepare. Create a gluten-free pizza crust that is crispy on the outside and chewy on the inside. Design a low-calorie, high-fiber soup that is perfect for weight loss. Develop a meal prep-friendly, healthy lunch that can be reheated easily. Create a plant-based burger that is juicy and flavorful. Design a dairy-free, nut-free ice cream that is creamy and indulgent. Develop a spicy, Mexican-inspired dish that is perfect for a party. Create a gluten-free, one-pot pasta dish that is comforting and satisfying. Design a low-sodium, heart-healthy dinner for two. Develop a kid-friendly, picky-eater approved meal that is packed with vegetables. Create a vegan, chocolate dessert that is rich and fudgy. Design a high-protein, low-carb smoothie that is perfect for breakfast or a snack. Develop a gluten-free, dairy-free pancakes recipe that is fluffy and delicious. Create a budget-friendly, family-friendly dinner that is easy to make. Develop a paleo-friendly, whole30 compliant dinner. Create a low-FODMAP, gluten-free, dairy-free dessert. Design a high-protein, low-fat snack for weight management. Develop a vegetarian, Asian-inspired stir-fry with a variety of textures. Create a kid-friendly, lunchbox-friendly meal with hidden vegetables. Design a diabetic-friendly, low-glycemic index dessert. Develop a seafood-based dish with bold, Mediterranean flavors. Create a gluten-free, dairy-free pizza crust using cauliflower. Design a plant-based, protein-rich bowl meal for lunch or dinner. Develop a quick and easy, one-pan dinner for busy weeknights. Create a low-sodium, heart-healthy soup packed with flavor. Design a high-fiber, gut-friendly breakfast with probiotics. Develop a vegan, chocolate-free dessert that is equally indulgent. Create a kid-friendly, picky-eater approved pasta dish. Design a low-carb, high-fat snack that is portable and satisfying. Develop a gluten-free, dairy-free pancakes with a fluffy texture. Create a budget-friendly, family-friendly meal using pantry staples. Design a vegetarian, Mexican-inspired dish with bold flavors. Develop a high-protein, low-carb smoothie bowl with toppings. Create a gluten-free, dairy-free ice cream alternative using frozen bananas. Develop a low-sodium, heart-healthy stir-fry with Asian-inspired flavors. Create a vegan, gluten-free, high-protein pasta dish using lentil pasta. Design a dairy-free, nut-free, chocolate-based dessert. Develop a keto-friendly, high-fat breakfast with avocado as a base. Create a vegetarian, Mexican-inspired chili with a smoky flavor. Design a gluten-free, dairy-free pancakes using almond flour. Develop a low-carb, high-protein snack bar using protein powder. Create a kid-friendly, healthy lunchbox meal with hummus and fresh vegetables. Design a vegan, creamy soup without dairy or cream. Develop a gluten-free, dairy-free pizza crust using coconut flour. Create a Mediterranean-inspired salad with grilled chicken or tofu. Design a low-sugar, high-fiber dessert using fruit as a sweetener. Develop a pescatarian, seafood-based chowder with a creamy texture. Create a kid-friendly, picky-eater approved smoothie with hidden vegetables. Design a low-carb, high-fat breakfast with eggs as the main ingredient. Develop a vegan, gluten-free, high-protein energy balls. Create a Mediterranean-inspired grain bowl with a variety of toppings. Design a dairy-free, nut-free ice cream alternative using coconut milk. Develop a low-sodium, heart-healthy soup with a bold flavor profile. Create a kid-friendly, healthy lunchbox meal with leftovers. Develop a low-carb, high-protein breakfast smoothie bowl with chia seeds. Create a vegetarian, Indian-inspired lentil curry with coconut milk. Design a gluten-free, dairy-free, chocolate avocado mousse. Develop a keto-friendly, high-fat snack with bacon and cheese. Create a kid-friendly, healthy lunchbox meal with leftover chicken. Design a diabetic-friendly, low-glycemic index fruit salad with protein. Develop a pescatarian, seafood-based paella with saffron rice. Create a gluten-free, dairy-free pancakes with coconut oil. Design a plant-based, protein-rich buddha bowl with quinoa. Develop a quick and easy, one-pan chicken and vegetable dinner. Create a low-sodium, heart-healthy grilled salmon with roasted vegetables. Design a high-fiber, gut-friendly smoothie with spinach and berries. Develop a vegan, chocolate-free dessert using dates and nuts. Create a kid-friendly, picky-eater approved pizza with healthy toppings. Design a low-carb, high-fat snack with avocado and smoked salmon. Develop a gluten-free, dairy-free pancakes with coconut milk and blueberries. Create a budget-friendly, family-friendly pasta dish with ground turkey. Design a vegetarian, Mexican-inspired enchiladas with a spicy sauce. Develop a high-protein, low-carb breakfast frittata with vegetables. Create a gluten-free, dairy-free ice cream alternative using frozen bananas and cacao. Develop a low-carb, high-protein lunch salad with grilled shrimp. Create a vegetarian, Indian-inspired chickpea curry with spinach. Design a gluten-free, dairy-free, no-bake cheesecake with fruit topping. Develop a keto-friendly, high-fat snack with almond butter and celery. Create a kid-friendly, healthy lunchbox meal with turkey and cheese roll-ups. Design a diabetic-friendly, low-glycemic index Greek yogurt parfait. Develop a pescatarian, seafood-based soup with clams and mussels. Create a gluten-free, dairy-free pancakes with chia seeds and maple syrup. Design a plant-based, protein-rich power bowl with brown rice. Develop a quick and easy, one-pan salmon with roasted asparagus. Create a low-sodium, heart-healthy lentil soup with vegetables. Design a high-fiber, gut-friendly smoothie with flaxseed and probiotics. Develop a vegan, chocolate-free dessert using avocado and cocoa powder. Create a kid-friendly, picky-eater approved chicken nuggets with sweet potato fries. Design a low-carb, high-fat snack with hard-boiled eggs and avocado. Develop a gluten-free, dairy-free pancakes with coconut flour and almond milk. Create a budget-friendly, family-friendly chili with ground beef. Design a vegetarian, Mexican-inspired burrito bowl with black beans. Develop a high-protein, low-carb breakfast omelet with spinach and feta. Create a gluten-free, dairy-free ice cream alternative using frozen berries and coconut cream. ================================================ FILE: pyopenagi/data/agent_tasks/example/creation_agent_task.txt ================================================ Create an Instagram post: Image of a person using a new tech gadget, text highlighting its key features and benefits. Design a Facebook ad: Image of a delicious meal, text emphasizing taste, freshness, and affordability. Develop a Twitter post: Image of a striking natural landscape, text inspiring travel and adventure. Create an Instagram story: Image of a fitness enthusiast doing a challenging workout, text motivating viewers to exercise. Design a Facebook cover photo: Image of a bustling city skyline, text representing a dynamic and innovative company. Develop a Twitter header: Image of a serene beach, text promoting relaxation and wellness. Create an Instagram post: Image of a fashion model wearing the latest collection, text emphasizing style and luxury. Design a Facebook ad: Image of a family enjoying a product, text highlighting its benefits for the whole family. Develop a Twitter post: Image of a company logo with a vibrant color scheme, text conveying a strong brand message. Create an Instagram post: Image of people volunteering for a cause, text inspiring viewers to give back. Design a Facebook cover photo: Image of a diverse group of people, text promoting inclusivity and equality. Develop a Twitter post: Image of a climate change-related issue, text calling for action and awareness. Create an Instagram post: Image of festive decorations, text wishing followers a happy holiday. Design a Facebook ad: Image of a gift wrapped in colorful paper, text promoting holiday sales. Develop a Twitter post: Image of a traditional holiday dish, text sharing a holiday recipe. Create an Instagram post: Image of a minimalist design, text conveying a powerful message. Design a Facebook cover photo: Image using only black and white, text creating a strong visual impact. Develop a Twitter post: Image with a surprising twist, text generating curiosity. Create an Instagram post: Image in a square format, text maximizing impact in limited space. Design a Facebook cover photo: Image optimizing for desktop and mobile views, text adaptable to different screen sizes. Develop a Twitter post: Image and text fitting within character limits, conveying a clear message. Create an Instagram post: Image of an influencer using a product, text highlighting the influencer's endorsement. Design a Facebook cover photo: Image of an influencer and brand together, text emphasizing the partnership. Develop a Twitter post: Image of an influencer sharing a product, text encouraging followers to try it. Create an Instagram post: Image conveying empathy and understanding, text apologizing for a mistake. Design a Facebook cover photo: Image representing company values, text reassuring customers of commitment. Develop a Twitter post: Image symbolizing transparency, text acknowledging a problem and outlining solutions. Create an Instagram post: Image showcasing user-generated content, text thanking followers for sharing. Design a Facebook cover photo: Image featuring a collage of user-submitted photos, text encouraging participation. Develop a Twitter post: Image highlighting a standout user-generated post, text praising the creator. Create an Instagram post featuring a behind-the-scenes look at product creation, with text emphasizing craftsmanship and attention to detail. Design a Facebook cover photo showcasing a diverse team collaborating on a project, with text promoting teamwork and innovation. Develop a Twitter post featuring a customer testimonial, with text highlighting product satisfaction and loyalty. Create an Instagram post featuring a limited-time offer, with text creating urgency and excitement. Design a Facebook cover photo showcasing a global map, with text emphasizing the company's international reach. Develop a Twitter post featuring a thought-provoking question related to the industry, with text encouraging engagement and discussion. Create an Instagram post featuring a before-and-after transformation, with text highlighting product efficacy. Design a Facebook cover photo showcasing a charity partnership, with text emphasizing corporate social responsibility. Develop a Twitter post featuring a user-generated content highlight, with text thanking the customer and encouraging others to share. Create an Instagram post featuring a product comparison chart, with text explaining the benefits of choosing the company's product. Design a Facebook cover photo showcasing a company milestone, with text celebrating achievements and thanking customers. Develop a Twitter post featuring an industry award or recognition, with text expressing gratitude and sharing the honor. Create an Instagram post featuring a seasonal product, with text emphasizing its relevance to the current time of year. Design a Facebook cover photo showcasing a customer event or gathering, with text fostering a sense of community. Develop a Twitter post featuring a fun fact about the company or product, with text engaging the audience with trivia. Create an Instagram post featuring a product bundle or package deal, with text highlighting the value proposition. Design a Facebook cover photo showcasing a company's commitment to sustainability, with text emphasizing eco-friendly practices. Develop a Twitter post featuring a customer complaint response, with text demonstrating excellent customer service and problem-solving. Create an Instagram post featuring a product giveaway or contest, with text generating excitement and encouraging participation. Design a Facebook cover photo showcasing a company's core values, with text inspiring employees and customers. Develop a Twitter post featuring a company blog post or article, with text summarizing key points and encouraging reading. Create an Instagram post featuring a product demonstration video, with text highlighting key features and benefits. Design a Facebook cover photo showcasing a company's office or workspace culture, with text promoting a positive work environment. Develop a Twitter post featuring a company's involvement in a local community event, with text emphasizing corporate citizenship. Create an Instagram post featuring a customer success story, with text inspiring potential customers and building trust. Design a Facebook cover photo showcasing a company's vision for the future, with text inspiring employees and customers. Develop a Twitter post featuring a company's response to a current trend or news event, with text demonstrating relevance and engagement. Design a Facebook cover photo showcasing a company milestone, with text celebrating achievements and thanking customers. Develop a Twitter post featuring an industry award or recognition, with text expressing gratitude and sharing the honor. Create an Instagram post featuring a seasonal product, with text emphasizing its relevance to the current time of year. Design a Facebook cover photo showcasing a customer event or gathering, with text fostering a sense of community. Develop a Twitter post featuring a fun fact about the company or product, with text engaging the audience with trivia. Create an Instagram post featuring a product bundle or package deal, with text highlighting the value proposition. Design a Facebook cover photo showcasing a company's commitment to sustainability, with text emphasizing eco-friendly practices. Develop a Twitter post featuring a customer complaint response, with text demonstrating excellent customer service and problem-solving. Create an Instagram post featuring a product giveaway or contest, with text generating excitement and encouraging participation. Design a Facebook cover photo showcasing a company's core values, with text inspiring employees and customers. Develop a Twitter post featuring a company blog post or article, with text summarizing key points and encouraging reading. Create an Instagram post featuring a product demonstration video, with text highlighting key features and benefits. Design a Facebook cover photo showcasing a company's office or workspace culture, with text promoting a positive work environment. Develop a Twitter post featuring a company's involvement in a local community event, with text emphasizing corporate citizenship. Create an Instagram post featuring a customer success story, with text inspiring potential customers and building trust. Design a Facebook cover photo showcasing a company's vision for the future, with text inspiring employees and customers. Develop a Twitter post featuring a company's response to a current trend or news event, with text demonstrating relevance and engagement. Create an Instagram post featuring a product giveaway or contest, with text generating excitement and encouraging participation. Design a Facebook cover photo showcasing a company's core values, with text inspiring employees and customers. Develop a Twitter post featuring a company blog post or article, with text summarizing key points and encouraging reading. Create an Instagram post featuring a product demonstration video, with text highlighting key features and benefits. Design a Facebook cover photo showcasing a company's office or workspace culture, with text promoting a positive work environment. Develop a Twitter post featuring a company's involvement in a local community event, with text emphasizing corporate citizenship. Create an Instagram post featuring a customer success story, with text inspiring potential customers and building trust. Design a Facebook cover photo showcasing a company's vision for the future, with text inspiring employees and customers. Develop a Twitter post featuring a company's response to a current trend or news event, with text demonstrating relevance and engagement. Create an Instagram post featuring a product giveaway or contest, with text generating excitement and encouraging participation. Design a Facebook cover photo showcasing a company's core values, with text inspiring employees and customers. Develop a Twitter post featuring a company blog post or article, with text summarizing key points and encouraging reading. Create an Instagram post featuring a product demonstration video, with text highlighting key features and benefits. Design a Facebook cover photo showcasing a company's office or workspace culture, with text promoting a positive work environment. Develop a Twitter post featuring a company's involvement in a local community event, with text emphasizing corporate citizenship. Create an Instagram post featuring a customer success story, with text inspiring potential customers and building trust. Design a Facebook cover photo showcasing a company's vision for the future, with text inspiring employees and customers. Develop a Twitter post featuring a company's response to a current trend or news event, with text demonstrating relevance and engagement. Create an Instagram post featuring a product giveaway or contest, with text generating excitement and encouraging participation. Design a Facebook cover photo showcasing a company's core values, with text inspiring employees and customers. Develop a Twitter post featuring a company blog post or article, with text summarizing key points and encouraging reading. Create an Instagram post featuring a product demonstration video, with text highlighting key features and benefits. Design a Facebook cover photo showcasing a company's office or workspace culture, with text promoting a positive work environment. Develop a Twitter post featuring a company's involvement in a local community event, with text emphasizing corporate citizenship. Create an Instagram post featuring a customer success story, with text inspiring potential customers and building trust. Design a Facebook cover photo showcasing a company's vision for the future, with text inspiring employees and customers. ================================================ FILE: pyopenagi/data/agent_tasks/example/fashion_stylist_task.txt ================================================ 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. Create 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. Develop 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. Design a wedding dress for a bohemian bride with a free-spirited personality, incorporating lace, floral motifs, and a flowing silhouette. Create 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. Design a casual outfit for a teenage girl with a sporty aesthetic, incorporating athleisure elements into a fashionable look, using vibrant colors and comfortable fabrics. Create 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. Develop a boho-chic outfit for a woman in her 20s with a slender build, incorporating flowy fabrics, earthy tones, and layered accessories. Design 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. Create a festival-inspired outfit for a woman in her late 20s with a bohemian spirit, incorporating vibrant patterns, fringe, and comfortable footwear. Design 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. Create 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. Develop 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. Design a uniform for a healthcare professional that prioritizes both function and style, incorporating modern design elements and using comfortable, easy-care fabrics. Create a corporate attire for a woman with a petite frame, emphasizing sophistication and professionalism, using tailored cuts and high-quality fabrics. Design a cyberpunk-inspired outfit for a young adult with a rebellious spirit, incorporating metallic accents, dark colors, and futuristic silhouettes. Create a vintage-inspired dress for a woman in her 20s with a romantic style, using delicate fabrics, lace, and feminine details. Develop a gothic-inspired outfit for a teenager with a dark aesthetic, incorporating black, leather, and edgy accessories. Design a minimalist outfit for a man in his 30s with a clean and modern style, using neutral colors and simple lines. Create a maximalist outfit for a woman in her 40s with a bold personality, incorporating vibrant colors, patterns, and textures. Design a prom dress for a teenage girl with a curvy figure, focusing on a glamorous and sophisticated look, using sparkling fabrics and intricate details. Create a Halloween costume for a family of five, based on a popular movie or TV show, incorporating group coordination and creativity. Develop a maternity photoshoot outfit for a couple expecting twins, combining stylish and comfortable elements for both parents. Design a costume for a Renaissance fair, focusing on historical accuracy and comfort, using natural fabrics and earthy tones. Create a New Year's Eve outfit for a woman in her 20s, incorporating sparkle, glamour, and a touch of edginess. Design a swimsuit for a woman with a pear-shaped body, emphasizing her waist and creating a balanced silhouette. Create a workout outfit for a man with a muscular build, focusing on comfort and support, using moisture-wicking fabrics and athletic cuts. Develop a winter coat for a petite woman, prioritizing warmth and style, using a flattering length and incorporating trendy details. Design a jeans and t-shirt outfit for a plus-size woman, focusing on comfort and confidence, using flattering cuts and stylish accessories. Create a formal gown for a tall and slender woman, emphasizing elegance and sophistication, using flowing fabrics and clean lines. Design a collection inspired by the art deco movement, incorporating geometric shapes, metallic accents, and luxurious fabrics. Create a line of clothing based on the concept of "slow fashion," emphasizing sustainability, quality, and timeless design. Develop a collection inspired by the natural world, using organic materials and incorporating elements like flora and fauna. Design a line of activewear that is both functional and stylish, catering to a variety of fitness activities. Create a collection of evening wear inspired by different cultures around the world, incorporating traditional elements with modern interpretations. Design a line of handbags for professional women, focusing on functionality and style, incorporating high-quality materials and organizational features. Create a collection of footwear for men that combines comfort and fashion, catering to different occasions and personal styles. Develop a line of jewelry inspired by nature, using organic materials and delicate craftsmanship. Design a collection of sunglasses that are both functional and fashionable, offering a variety of shapes and lens options. Create a line of hats for women that complement different head shapes and hair styles, incorporating various materials and designs. Design a collection of clothing for teenage boys who are into skateboarding and streetwear culture. Create a line of maternity wear that is both stylish and comfortable, catering to the needs of modern expectant mothers. Develop a collection of clothing for older women who value comfort and style, incorporating classic elements with contemporary touches. Design a line of clothing for plus-size men, focusing on fit, style, and confidence-boosting designs. Create a collection of clothing for people with disabilities, prioritizing accessibility, comfort, and fashion. Design a costume for a character in a historical drama, researching the period accurately and incorporating authentic details. Create a collection of wearable technology, combining fashion and function in innovative ways. Develop a line of clothing for virtual reality experiences, considering the needs of the user and the virtual environment. Design a collection of upcycled clothing, using repurposed materials to create unique and sustainable fashion pieces. Create a line of gender-neutral clothing, challenging traditional gender norms and offering versatile options. Design a collection of formal wear for a black-tie gala with a Hollywood Regency theme. Create a line of clothing for a music festival with a psychedelic, bohemian vibe. Develop a collection of bridal attire for destination weddings in tropical locations. Design a line of clothing for a steampunk-themed event, incorporating gears, leather, and Victorian elements. Create a collection of outfits for a masquerade ball, focusing on dramatic masks and elegant gowns. Design a collection of clothing made entirely from recycled materials, exploring innovative techniques and aesthetics. Create a line of adaptive clothing for people with mobility challenges, prioritizing both function and style. Develop a collection of smart clothing incorporating technology for performance enhancement or data tracking. Design a line of clothing for virtual and augmented reality experiences, considering the needs of the user and the digital environment. Create a collection of gender-fluid clothing that challenges traditional gender norms and offers versatile options. Design a line of clothing for professional women in the tech industry, combining style and comfort with practicality. Create a collection of clothing for plus-size men who want to look stylish and confident. Develop a line of clothing for teenage girls who are interested in alternative fashion and subcultures. Design a collection of clothing for older men who appreciate classic styles with a modern twist. Create a line of clothing for people who are environmentally conscious and prefer sustainable fashion. Design a collection of clothing inspired by the concept of "slow fashion," emphasizing sustainability, quality, and longevity. Create a line of clothing using only natural fibers like cotton, wool, and linen. Develop a collection of clothing inspired by the art and architecture of a specific city. Design a line of clothing that incorporates elements of traditional craftsmanship and modern aesthetics. Create a collection of clothing inspired by the concept of "gender fluidity," offering versatile pieces for all body types and identities. Design a line of clothing for athletes who prioritize both performance and style. Create a collection of clothing for people with specific dietary restrictions or allergies, using hypoallergenic materials. Develop a line of clothing for travelers who value comfort, versatility, and packing efficiency. Design a collection of clothing for people who work in creative industries, emphasizing individuality and self-expression. Create a line of clothing for people who are interested in cosplay and character dressing. Design a collection of clothing for a black-tie wedding with a modern, minimalist aesthetic. Create a line of clothing for a music festival with a country-western theme. Develop a collection of clothing for a formal garden party. Design a line of clothing for a Halloween party with a superhero theme. Create a collection of clothing for a winter wonderland-themed event. Design a collection of clothing incorporating sustainable materials and production processes. Create a line of clothing inspired by the concept of "wearable technology," integrating technology into fashion pieces. Develop a collection of clothing that focuses on inclusivity and diversity, catering to a wide range of body types and ethnicities. Design a line of clothing inspired by the concept of "capsule wardrobe," offering versatile pieces that can be mixed and matched. Create a collection of clothing that incorporates elements of traditional craftsmanship and modern technology. Design a collection of clothing using only a limited color palette of neutrals. Create a line of clothing inspired by the art of origami, incorporating folded and layered elements. Develop a collection of clothing using only recycled materials. Design a line of clothing inspired by the concept of "zero waste," minimizing material waste during production. Create a collection of clothing inspired by the beauty of imperfection, embracing unique textures and irregularities. Design a collection of clothing inspired by the concept of "slow fashion," emphasizing sustainability, quality, and longevity. Create a line of clothing using only natural fibers like cotton, wool, and linen. Develop a collection of clothing inspired by the art and architecture of a specific city. Design a line of clothing that incorporates elements of traditional craftsmanship and modern aesthetics. Create a collection of clothing inspired by the concept of "gender fluidity," offering versatile pieces for all body types and identities. Design a collection of clothing inspired by the concept of "wearable technology," integrating technology into fashion pieces. Develop a collection of clothing that focuses on inclusivity and diversity, catering to a wide range of body types and ethnicities. Design a line of clothing inspired by the concept of "capsule wardrobe," offering versatile pieces that can be mixed and matched. Create a collection of clothing that incorporates elements of traditional craftsmanship and modern technology. ================================================ FILE: pyopenagi/data/agent_tasks/example/festival_card_designer_task.txt ================================================ Design a festival card for a vintage-themed music festival targeting young adults, with a square card size. Create a psychedelic-inspired card for an electronic music festival aimed at a millennial audience, using a standard postcard size. Design a minimalist card for a yoga and wellness festival targeting health-conscious adults, with a large square format. Develop a boho-chic card for a camping and music festival appealing to young adults and families, using a standard postcard size. Create a glamorous card for a film festival targeting a mature audience, with a large square format. Design a rustic card for a country music festival appealing to middle-aged adults, using a standard postcard size. Develop a futuristic card for a technology and music festival targeting young adults, with a square card size. Create a tropical card for a beach music festival aimed at a young adult audience, using a standard postcard size. Design a gothic card for a horror film festival targeting young adults, with a large square format. Develop a whimsical card for a children's festival appealing to families, using a standard postcard size. Design a festival card with a mermaid theme for a coastal music festival targeting young women. Create a card with a cyberpunk aesthetic for a gaming and music festival aimed at teenagers. Design a card with a floral pattern for a spring music festival targeting young adults. Develop a card with a mountain landscape for a hiking and music festival appealing to outdoor enthusiasts. Create a card with a starry night sky for an astronomy festival targeting families. Design a card with a food truck theme for a street food festival aimed at young adults. Develop a card with a circus theme for a family-friendly festival appealing to all ages. Create a card with a masquerade theme for a formal gala and music festival targeting adults. Design a card with a graffiti art style for an urban music festival aimed at young adults. Develop a card with a vintage car theme for a classic car show and music festival appealing to middle-aged adults. Design a festival card with a desert oasis theme for a electronic music festival targeting young adults. Create a card with a steampunk aesthetic for a cosplay and music festival aimed at teenagers. Design a card with a watercolor floral pattern for a wedding festival targeting couples. Develop a card with a forest animal theme for a nature festival appealing to families. Create a card with a galaxy theme for a science fiction festival targeting young adults. Design a card with a carnival theme for a summer festival aimed at all ages. Develop a card with a wine tasting theme for a food and wine festival appealing to adults. Create a card with a rock and roll theme for a classic rock music festival targeting middle-aged adults. Design a card with a tropical bird theme for a birdwatching festival aimed at nature enthusiasts. Develop a card with a renaissance fair theme for a historical reenactment festival appealing to families. Design a card with a superhero theme for a comic-con festival targeting young adults. Create a card with a vintage typography style for a poetry and music festival aimed at adults. Design a card with a chalkboard background for a farmer's market festival targeting families. Develop a card with a neon lights aesthetic for an electronic dance music festival appealing to young adults. Create a card with a fairytale theme for a children's storytelling festival targeting families. Design a card with a jazz club atmosphere for a jazz music festival aimed at adults. Develop a card with a sports theme for a sports and music festival appealing to young adults. Create a card with a gothic castle theme for a fantasy literature festival targeting young adults. Design a card with a underwater world theme for a marine life festival aimed at families. Develop a card with a bohemian pattern for a world music festival appealing to young adults. Design a card with a holographic aesthetic for a futuristic music festival targeting young adults. Create a card with a vintage travel poster style for a music and camping festival aimed at young adults. Design a card with a botanical illustration style for a garden party festival targeting adults. Develop a card with a grunge aesthetic for a rock music festival appealing to young adults. Create a card with a masquerade ball theme for a formal dance and music festival targeting adults. Design a card with a pixel art style for a retro gaming festival aimed at young adults. Develop a card with a harvest theme for a fall festival appealing to families. Create a card with a circus big top theme for a family-friendly circus festival targeting all ages. Design a card with a space exploration theme for a science fiction convention and music festival aimed at young adults. Develop a card with a Moroccan pattern for a world music and dance festival appealing to adults. Design a card with a cyberpunk city skyline for a futuristic technology festival targeting young adults. Create a card with a vintage record player theme for a vinyl record collectors festival aimed at adults. Design a card with a watercolor galaxy for a space-themed music festival targeting young adults. Develop a card with a farm animal theme for a country living festival appealing to families. Create a card with a gothic cathedral theme for a classical music festival targeting adults. Design a card with a tropical island paradise theme for a beach party festival aimed at young adults. Develop a card with a wine barrel theme for a vineyard festival appealing to adults. Create a card with a graffiti art mural theme for an urban culture festival targeting young adults. Design a card with a fairytale castle theme for a princess-themed children's festival aimed at young girls. Develop a card with a desert cactus theme for a southwestern music festival appealing to adults. Design a card with a vintage circus poster style for a retro-themed festival aimed at adults. Create a card with a holographic rainbow theme for a pride festival targeting the LGBTQ+ community. Design a card with a watercolor sunset over the ocean for a beach music festival aimed at young adults. Develop a card with a gothic gargoyle theme for a horror-themed music festival appealing to young adults. Create a card with a fairytale forest theme for a fantasy literature festival targeting young adults. Design a card with a neon graffiti art style for an urban street festival aimed at young adults. Develop a card with a vintage typewriter theme for a writer's festival appealing to adults. Create a card with a cosmic astronaut theme for a space-themed music festival targeting young adults. Design a card with a watercolor floral wreath for a garden party festival aimed at adults. Develop a card with a steampunk airship theme for a steampunk convention and music festival appealing to young adults. Design a card with a psychedelic mushroom theme for a rave festival aimed at young adults. Create a card with a vintage typewriter and quill pen theme for a literary festival appealing to adults. Design a card with a watercolor mountain range for a hiking and camping festival aimed at young adults. Develop a card with a gothic vampire theme for a horror-themed music festival appealing to young adults. Create a card with a fairytale princess theme for a children's ball aimed at young girls. Design a card with a neon palm tree theme for a tropical music festival aimed at young adults. Develop a card with a wine grapevine theme for a harvest festival appealing to adults. Create a card with a graffiti-covered subway car theme for an urban music festival aimed at young adults. Design a card with a watercolor mermaid theme for a beach-themed music festival aimed at young adults. Develop a card with a steampunk robot theme for a technology and music festival appealing to young adults. Design a card with a psychedelic galaxy theme for a space-themed music festival aimed at young adults. Create a card with a vintage book cover theme for a literary festival appealing to adults. Design a card with a watercolor forest scene for a nature and music festival aimed at young adults. Develop a card with a gothic werewolf theme for a horror-themed music festival appealing to young adults. Create a card with a fairytale dragon theme for a fantasy literature festival targeting young adults. Design a card with a neon cityscape theme for an urban music festival aimed at young adults. Develop a card with a wine glass and grapes theme for a wine tasting festival appealing to adults. Create a card with a graffiti-covered wall theme for an urban art festival aimed at young adults. Design a card with a watercolor underwater scene for a marine life festival aimed at families. Develop a card with a steampunk airship battle theme for a steampunk convention and music festival appealing to young adults. Design a festival card for a music festival with a psychedelic, space-themed atmosphere. Create a card for a music festival with a bohemian, nature-inspired vibe. Design a card for a music festival with a futuristic, cyberpunk aesthetic. Create a card for a music festival with a vintage, retro feel. Design a card for a music festival with a tropical, beach party atmosphere. Create a card for a music festival with a grunge, underground scene vibe. Design a card for a music festival with a luxurious, upscale feel. Create a card for a music festival with a family-friendly, carnival atmosphere. Design a card for a music festival with a minimalist, modern aesthetic. Create a card for a music festival with a magical, enchanted forest theme. ================================================ FILE: pyopenagi/data/agent_tasks/example/fitness_trainer_task.txt ================================================ Create a workout plan for a busy professional aiming to lose 10 pounds in 3 months. Design a strength training routine for a beginner focusing on building muscle mass. Develop a cardio-based workout plan for someone recovering from a knee injury. Create a balanced workout routine for a vegetarian athlete training for a marathon. Design a home workout plan for a mother of two with limited equipment. Develop a post-pregnancy workout plan focusing on core strength and pelvic floor health. Create a workout plan for a senior citizen aiming to improve balance and flexibility. Design a high-intensity interval training (HIIT) workout for someone looking to burn calories fast. Develop a bodyweight workout plan for a traveler with no access to a gym. Create a workout plan for an office worker suffering from chronic back pain. Design a workout plan for a golfer aiming to improve swing power and flexibility. Develop a strength training routine for a rock climber focusing on upper body strength. Create a cardio workout plan for a swimmer looking to increase endurance. Design a workout plan for a dancer aiming to improve strength, flexibility, and balance. Develop a strength training routine for a tennis player focusing on core stability and power. Create a workout plan for a cyclist aiming to improve leg strength and endurance. Design a workout plan for a basketball player focusing on agility and explosiveness. Develop a workout plan for a soccer player aiming to improve speed and stamina. Create a workout plan for a volleyball player focusing on jumping power and arm strength. Design a workout plan for a martial artist aiming to improve strength, flexibility, and balance. Create a beginner-friendly yoga workout plan for stress relief. Design a modified workout plan for someone with arthritis in their hands. Develop a low-impact workout plan for someone with plantar fasciitis. Create a workout plan for an overweight individual starting their fitness journey. Design a workout plan for a highly fit individual looking to build muscle and strength. Develop a workout plan for someone with asthma focusing on cardio and strength. Create a workout plan for someone with diabetes focusing on blood sugar control. Design a workout plan for someone with osteoporosis focusing on bone health. Develop a workout plan for someone with high blood pressure focusing on endurance. Create a workout plan for someone with vertigo focusing on balance and stability. Create a meal plan for a vegan athlete training for a triathlon. Create a workout plan for a vegan bodybuilder aiming to increase muscle mass. Design a workout plan for a person with lactose intolerance focusing on calcium intake. Develop a workout plan for a competitive eater looking to improve overall fitness. Create a workout plan for a fashion model aiming to tone and lengthen muscles. Design a workout plan for a professional gamer to improve posture and reduce back pain. Develop a workout plan for a firefighter aiming to improve cardiovascular endurance. Create a workout plan for a police officer focusing on upper body strength and agility. Design a workout plan for a construction worker aiming to prevent injuries. Develop a workout plan for a chef to improve stamina and balance. Create a workout plan for a software engineer to combat sedentary lifestyle. Create a workout plan using only resistance bands for a home workout. Design a bodyweight workout plan for a park setting. Develop a workout plan using dumbbells for a home gym. Create a workout plan using a kettlebell for full-body strength training. Design a workout plan using a treadmill and elliptical for cardio. Develop a workout plan using a swimming pool for water resistance training. Create a workout plan using a yoga mat for flexibility and core strength. Design a workout plan using a gym with full equipment access. Develop a workout plan using a small apartment with limited space. Create a workout plan using a hotel gym with basic equipment. Create a 30-day ab challenge workout plan. Design a 4-week weight loss challenge workout plan. Develop a 6-week muscle building challenge workout plan. Create a 12-week half marathon training plan. Design a full-body circuit workout for maximum calorie burn. Develop a plyometric workout for improving explosive power. Create a yoga flow sequence for flexibility and relaxation. Design a pilates workout for core strength and stability. Develop a barre workout for toning and lengthening muscles. Create a TRX suspension trainer workout for full-body strength. Create a prenatal workout plan focusing on safety and well-being. Design a postpartum workout plan for recovering mothers. Develop a workout plan for teenagers to improve fitness and confidence. Create a workout plan for people with disabilities focusing on accessibility. Design a workout plan for athletes recovering from injuries. Develop a workout plan for firefighters to improve strength and endurance. Create a workout plan for police officers to enhance fitness and agility. Design a workout plan for military personnel to build physical resilience. Develop a workout plan for healthcare workers to manage stress and fatigue. Create a workout plan for teachers to improve energy and focus. Create a workout plan to reduce anxiety and stress. Design a workout plan to improve sleep quality. Develop a workout plan to boost mood and energy levels. Create a workout plan to enhance focus and concentration. Design a workout plan to build self-confidence and body positivity. Develop a workout plan to manage symptoms of depression. Create a workout plan to improve overall mental well-being. Design a workout plan to increase resilience and adaptability. Develop a workout plan to enhance creativity and problem-solving skills. Create a workout plan to cultivate mindfulness and presence. Create a workout plan that can be followed using a fitness tracker. Design a workout plan that incorporates virtual reality for an immersive experience. Develop a workout plan that uses wearable technology to monitor performance. Create a workout plan that can be streamed live online for group fitness. Create a workout plan that uses fitness apps to track progress and provide feedback. Design a workout plan that integrates smart home devices for a connected fitness experience. Develop a workout plan that utilizes gamification elements to enhance motivation. Create a workout plan that incorporates virtual fitness coaches for personalized guidance. Design a workout plan that uses heart rate monitors to optimize workout intensity. Create a workout plan for individuals with chronic fatigue syndrome. Design a workout plan for people with multiple sclerosis. Develop a workout plan for individuals with Parkinson's disease. Create a workout plan for people with fibromyalgia. Design a workout plan for individuals with rheumatoid arthritis. Create a workout plan for a night shift worker to optimize energy levels. Design a workout plan for a college student with a busy schedule. Develop a workout plan for a frequent traveler to maintain fitness on the road. Create a workout plan for a busy executive to fit exercise into a demanding lifestyle. Design a workout plan for a retired individual looking to stay active and healthy. ================================================ FILE: pyopenagi/data/agent_tasks/example/game_agent_task.txt ================================================ Recommend a relaxing puzzle game for Nintendo Switch, suitable for a casual player. Suggest a challenging action RPG for PC, targeting a hardcore gamer seeking a deep story. Find a multiplayer FPS for Xbox One that offers intense, competitive gameplay. Recommend a cooperative adventure game for PS4, ideal for a group of friends wanting a fun experience. Suggest a horror game for PC, suitable for someone who enjoys jump scares and intense atmosphere. Find a strategy game for Nintendo Switch, targeting a player looking for a deep, tactical experience. Recommend a racing game for Xbox One, suitable for a player who prefers arcade-style gameplay. Suggest a role-playing game for PS4, ideal for a player who enjoys character customization and open worlds. Find a sports game for PC, targeting a player who wants a realistic simulation experience. Recommend a platformer for Nintendo Switch, suitable for a player looking for a challenging and rewarding experience. Suggest a stealth game for PC, ideal for a player who enjoys planning and execution. Find a simulation game for Xbox One, targeting a player interested in managing a virtual world. Recommend a rhythm game for PS4, suitable for a player who loves music and wants to test their reflexes. Suggest a fighting game for PC, ideal for a competitive player seeking fast-paced action. Find a casual game for Nintendo Switch, suitable for a player looking to relax and unwind. Recommend a survival game for Xbox One, targeting a player who enjoys resource management and exploration. Suggest a puzzle-platformer for PS4, ideal for a player who likes challenges and brain-teasers. Find an open-world game for PC, targeting a player who wants endless possibilities and exploration. Recommend a multiplayer online battle arena (MOBA) for Nintendo Switch, suitable for a competitive player looking for fast-paced action. Suggest a massively multiplayer online role-playing game (MMORPG) for Xbox One, ideal for a player who enjoys social interaction and progression. Find a visual novel for PS4, targeting a player who enjoys storytelling and character development. Recommend a indie game for PC, suitable for a player looking for unique and innovative experiences. Suggest a party game for Nintendo Switch, ideal for a group of friends looking for fun and laughter. Find a card game for Xbox One, targeting a player who enjoys strategy and competition. Recommend a farming simulator for PS4, suitable for a player who enjoys relaxing gameplay and building a virtual farm. Suggest a space simulator for PC, ideal for a player interested in exploration and scientific discovery. Find a point-and-click adventure game for Nintendo Switch, targeting a player who enjoys puzzles and storytelling. Recommend a sports management game for Xbox One, suitable for a player who enjoys strategic decision-making. Suggest a battle royale game for PS4, ideal for a player who enjoys fast-paced, large-scale combat. Find a sandbox game for PC, targeting a player who enjoys creativity and experimentation. Recommend a stealth-action game for Nintendo Switch, suitable for a player who enjoys combining stealth and combat. Suggest a turn-based strategy game for Xbox One, ideal for a player who enjoys careful planning and tactical decisions. Find a role-playing game with a focus on character development for PS4, targeting a player who enjoys deep storylines and choices. Recommend a multiplayer co-op shooter for PC, suitable for a group of friends who enjoy teamwork and action. Suggest a racing game with a focus on realistic simulation for Xbox One, targeting a player who enjoys high-speed competition. Find a sports game with a focus on arcade-style gameplay for PS4, targeting a player who enjoys fast-paced and fun action. Recommend a puzzle game with a focus on logic and deduction for Nintendo Switch, suitable for a player who enjoys mental challenges. Suggest a horror game with a focus on psychological terror for PC, targeting a player who enjoys suspense and atmosphere. Find a platformer with a focus on precision and timing for Xbox One, suitable for a player who enjoys challenging gameplay. Recommend a simulation game with a focus on building and management for PS4, targeting a player who enjoys creating and growing. Suggest a rhythm game with a focus on dance and movement for PC, suitable for a player who enjoys physical activity and music. Find a fighting game with a focus on character customization for Xbox One, targeting a player who enjoys creating unique fighters. Recommend a casual game with a focus on time management for Nintendo Switch, suitable for a player who enjoys multitasking and challenges. Suggest a survival game with a focus on crafting and survival for PS4, targeting a player who enjoys resource management and exploration. Find a puzzle-platformer with a focus on environmental puzzles for PC, suitable for a player who enjoys using their surroundings to solve challenges. Recommend an open-world game with a focus on exploration and discovery for Xbox One, targeting a player who enjoys finding hidden secrets. Suggest a multiplayer online battle arena (MOBA) with a focus on teamwork and strategy for PS4, targeting a player who enjoys coordinated gameplay. Find 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. Recommend a visual novel with a focus on romance and relationships for Nintendo Switch, suitable for a player who enjoys character interactions. Suggest an indie game with a focus on pixel art for Xbox One, targeting a player who enjoys nostalgic and retro-style games. Recommend a party game with a focus on physical activity for PS4, suitable for a player who enjoys energetic and interactive gameplay. Suggest a card game with a focus on bluffing and deception for PC, targeting a player who enjoys social deduction games. Find a farming simulator with a focus on animal care for Nintendo Switch, suitable for a player who enjoys building relationships with virtual animals. Recommend a space simulator with a focus on combat and dogfights for Xbox One, targeting a player who enjoys fast-paced action in space. Suggest a point-and-click adventure game with a focus on humor and comedy for PS4, targeting a player who enjoys lighthearted storytelling. Find a sports management game with a focus on player development for PC, targeting a player who enjoys building a successful team. Recommend 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. Suggest a sandbox game with a focus on physics-based gameplay for Xbox One, targeting a player who enjoys experimentation and creativity. Find a stealth-action game with a focus on melee combat for PS4, targeting a player who enjoys close-quarters combat and stealth. Recommend a turn-based strategy game with a focus on hexagons for PC, suitable for a player who enjoys unique gameplay mechanics. Suggest a role-playing game with a focus on moral choices and consequences for Xbox One, targeting a player who enjoys making impactful decisions. Find a multiplayer co-op shooter with a focus on horror elements for PS4, suitable for a group of friends who enjoy cooperative scares. Recommend a racing game with a focus on drift racing for Nintendo Switch, suitable for a player who enjoys stylish and controlled driving. Suggest a sports game with a focus on extreme sports for PC, targeting a player who enjoys adrenaline-pumping action. Find a puzzle game with a focus on time travel for Xbox One, suitable for a player who enjoys mind-bending challenges. Recommend a horror game with a focus on survival horror for PS4, targeting a player who enjoys resource management and fear. Suggest a platformer with a focus on speedrunning for PC, suitable for a player who enjoys challenges and competition. Find a simulation game with a focus on city building for Nintendo Switch, suitable for a player who enjoys creating bustling metropolises. Recommend a rhythm game with a focus on vocaloid music for Xbox One, suitable for a player who enjoys Japanese pop culture. Suggest a fighting game with a focus on tag team battles for PS4, suitable for a player who enjoys cooperative gameplay. Find a casual game with a focus on puzzle solving for PC, suitable for a player who enjoys brain teasers and challenges. Recommend a survival game with a focus on base building for Xbox One, targeting a player who enjoys creating a fortified home. Suggest a puzzle-platformer with a focus on water mechanics for PS4, suitable for a player who enjoys unique gameplay elements. Find an open-world game with a focus on wildlife and nature for Nintendo Switch, suitable for a player who enjoys exploring the natural world. Recommend 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. Suggest 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. Find a visual novel with a focus on mystery and suspense for Nintendo Switch, suitable for a player who enjoys solving puzzles and unraveling secrets. Recommend an indie game with a focus on pixel art and platforming for Xbox One, targeting a player who enjoys challenging and nostalgic gameplay. Suggest a party game with a focus on trivia and knowledge for PS4, suitable for a group of friends who enjoy testing their wits. Find a card game with a focus on deck-building for PC, targeting a player who enjoys strategic planning and customization. Recommend 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. Suggest a space simulator with a focus on exploration and discovery of alien life for Xbox One, targeting a player who enjoys scientific exploration. Find 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. Recommend 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. Suggest a battle royale game with a focus on looting and scavenging for Nintendo Switch, suitable for a player who enjoys survival and resource management. Find a sandbox game with a focus on vehicle customization for Xbox One, targeting a player who enjoys creating unique and powerful vehicles. Recommend a stealth-action game with a focus on hacking and gadgets for PS4, suitable for a player who enjoys using technology to overcome challenges. Suggest a turn-based strategy game with a focus on diplomacy and negotiation for PC, targeting a player who enjoys social interaction and political maneuvering. Find a role-playing game with a focus on multiple playable characters for Xbox One, suitable for a player who enjoys experiencing different perspectives. Recommend 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. Suggest a racing game with a focus on open-world exploration for PC, suitable for a player who enjoys discovering hidden routes and landmarks. Find a sports game with a focus on online competition and leaderboards for Nintendo Switch, suitable for a player who enjoys challenging other players. Recommend a puzzle game with a focus on physics-based challenges for Xbox One, suitable for a player who enjoys using logic and experimentation. Suggest a horror game with a focus on first-person perspective for PS4, suitable for a player who enjoys immersive and intense experiences. Find a platformer with a focus on speed and agility for PC, suitable for a player who enjoys fast-paced and challenging gameplay. Recommend a simulation game with a focus on theme park management for Nintendo Switch, suitable for a player who enjoys creating and designing attractions. Suggest a rhythm game with a focus on karaoke for Xbox One, suitable for a player who enjoys singing and performing. Find a fighting game with a focus on projectile attacks for PS4, suitable for a player who enjoys long-range combat and strategy. Recommend a casual game with a focus on word puzzles for PC, suitable for a player who enjoys challenging their vocabulary. Suggest a survival game with a focus on base defense for Xbox One, suitable for a player who enjoys strategic planning and combat. ================================================ FILE: pyopenagi/data/agent_tasks/example/interior_decorator_task.txt ================================================ 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? My 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. Im 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. I 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. My 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? I 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? Im 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? I 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? Im 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? I 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? I 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? I 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? I 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? I 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? I 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? I 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? I 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? I 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? I 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? I 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? I 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? My 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? I 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? My 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? I 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? I 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? I'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? I 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? I'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? I 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? I 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? My 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? I 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? I 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? I 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? My 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? I 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? My 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? I 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? My 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? I'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? I 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? I'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? I 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? I'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? I 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? My 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? I 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? I 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? I 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? My 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? My 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? My 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? My 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? My mudroom is small and chaotic. I need help creating a functional and organized space. I love a classic, farmhouse style. Can you help me? I'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? I 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? I'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? I 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? I'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? I 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? My 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? I 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? My 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? I 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? My 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? My 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? My 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? My 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? My 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? I'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? I 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? I'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? I want to create a vibrant, tropical-inspired dining room. I have a small, square dining room with limited natural light. Can you help me? I'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? I 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? My 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? I 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? My 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? I 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? My 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? My 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? My 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? My 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? My 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? I'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? I 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? I'm interested in creating a minimalist, Japanese-inspired bedroom. I have a small, square room with limited storage. Can you help me? I 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? I'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? I 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? My 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? I 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? My 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? I 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? I 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? My 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? My bedroom has a vaulted ceiling and I want to create a focal point. I love a bohemian, eclectic style. Can you help me? My 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? My 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? ================================================ FILE: pyopenagi/data/agent_tasks/example/language_tutor_task.txt ================================================ Provide conversation practice for beginner level Arabic learners, focusing on basic greetings, introductions, and asking for directions. Help me improve my English presentation skills by providing tips on structure, delivery, and visual aids. Create a vocabulary list of 100 essential Vietnamese words related to family and relationships. Teach me basic grammar rules for Turkish sentence structure, including question formation and negation. Provide conversation practice for intermediate level Dutch learners, focusing on discussing work, hobbies, and travel. Help me improve my English reading comprehension by providing academic articles in various fields, with summaries and analysis questions. Create a vocabulary list of 100 essential Swedish words related to nature and the environment. Teach me basic grammar rules for Polish adjectives and their agreement with nouns. Provide conversation practice for advanced level German learners, focusing on business negotiations and presentations. Help me improve my English writing style through feedback on writing samples and suggestions for improving clarity and coherence. Create a vocabulary list of 100 essential Indonesian words related to education and learning. Teach me basic grammar rules for Vietnamese verb tenses and aspects. Provide conversation practice for beginner level Arabic learners, focusing on shopping and ordering food. Help me improve my English presentation skills by providing tips on overcoming stage fright and managing Q&A sessions. Create a vocabulary list of 100 essential Vietnamese words related to technology and the internet. Teach me basic grammar rules for Turkish pronouns and their usage in different sentence structures. Provide conversation practice for intermediate level Dutch learners, focusing on discussing current events and expressing opinions. Help me improve my English reading comprehension by providing literary texts with analysis questions and vocabulary building exercises. Create a vocabulary list of 100 essential Swedish words related to health and medicine. Teach me basic grammar rules for Polish prepositions and their usage in different contexts. Provide conversation practice for advanced level German learners, focusing on discussing philosophical and abstract topics. Help me improve my English writing style by providing feedback on writing samples and suggestions for improving style and tone. Create a vocabulary list of 100 essential Indonesian words related to government and politics. Teach me basic grammar rules for Vietnamese passive voice and its usage. Provide conversation practice for beginner level Arabic learners, discussing family and friends. Help me improve my English presentation skills by providing tips on creating effective visual aids. Create a vocabulary list of 100 essential Vietnamese words related to sports and recreation. Teach me basic grammar rules for Turkish conditional sentences and their usage. Provide conversation practice for intermediate level Dutch learners, focusing on discussing relationships and personal experiences. Help me improve my English reading comprehension by providing news articles with summaries and analysis questions. Provide conversation practice for beginner level Arabic learners, focusing on basic greetings, introductions, and asking for directions. Help me improve my English presentation skills by providing tips on structure, delivery, and visual aids. Create a vocabulary list of 100 essential Vietnamese words related to family and relationships. Teach me basic grammar rules for Turkish sentence structure, including question formation and negation. Provide conversation practice for intermediate level Dutch learners, focusing on discussing work, hobbies, and travel. Help me improve my English reading comprehension by providing academic articles in various fields, with summaries and analysis questions. Create a vocabulary list of 100 essential Swedish words related to nature and the environment. Teach me basic grammar rules for Polish adjectives and their agreement with nouns. Provide conversation practice for advanced level German learners, focusing on business negotiations and presentations. Help me improve my English writing style through feedback on writing samples and suggestions for improving clarity and coherence. Create a vocabulary list of 100 essential Indonesian words related to education and learning. Teach me basic grammar rules for Vietnamese verb tenses and aspects. Provide conversation practice for beginner level Arabic learners, focusing on shopping and ordering food. Help me improve my English presentation skills by providing tips on overcoming stage fright and managing Q&A sessions. Create a vocabulary list of 100 essential Vietnamese words related to technology and the internet. Teach me basic grammar rules for Turkish pronouns and their usage in different sentence structures. Provide conversation practice for intermediate level Dutch learners, focusing on discussing current events and expressing opinions. Help me improve my English reading comprehension by providing literary texts with analysis questions and vocabulary building exercises. Create a vocabulary list of 100 essential Swedish words related to health and medicine. Teach me basic grammar rules for Polish prepositions and their usage in different contexts. Provide conversation practice for advanced level German learners, focusing on discussing philosophical and abstract topics. Help me improve my English writing style by providing feedback on writing samples and suggestions for improving style and tone. Create a vocabulary list of 100 essential Indonesian words related to government and politics. Teach me basic grammar rules for Vietnamese passive voice and its usage. Provide conversation practice for beginner level Arabic learners, discussing family and friends. Help me improve my English presentation skills by providing tips on creating effective visual aids. Create a vocabulary list of 100 essential Vietnamese words related to sports and recreation. Teach me basic grammar rules for Turkish conditional sentences and their usage. Provide conversation practice for intermediate level Dutch learners, focusing on discussing relationships and personal experiences. Help me improve my English reading comprehension by providing news articles with summaries and analysis questions. Provide conversation practice for beginner level Arabic learners, focusing on numbers, time, and dates. Provide conversation practice for intermediate level Arabic learners, focusing on discussing work, education, and career goals. Provide conversation practice for advanced level Arabic learners, focusing on political and social issues. Teach basic grammar rules for Arabic noun genders and number. Teach basic grammar rules for Arabic verb conjugation patterns. Create a vocabulary list of 100 essential Arabic words related to food and cooking. Create a vocabulary list of 100 essential Arabic words related to travel and transportation. Create a vocabulary list of 100 essential Arabic words related to business and finance. Provide conversation practice for beginner level Mandarin learners, focusing on basic greetings, introductions, and asking for help. Provide conversation practice for intermediate level Mandarin learners, focusing on discussing hobbies, interests, and personal life. Provide conversation practice for advanced level Mandarin learners, focusing on cultural differences and social customs. Teach basic grammar rules for Mandarin sentence structure, including subject-verb-object order. Teach basic grammar rules for Mandarin particles and their usage. Create a vocabulary list of 100 essential Mandarin words related to family and relationships. Create a vocabulary list of 100 essential Mandarin words related to shopping and dining out. Create a vocabulary list of 100 essential Mandarin words related to health and fitness. Provide conversation practice for beginner level French learners, focusing on ordering food and drinks. Provide conversation practice for intermediate level French learners, discussing fashion, trends, and personal style. Provide conversation practice for advanced level French learners, discussing art, literature, and philosophy. Teach basic grammar rules for French verb conjugations. Teach basic grammar rules for French articles and prepositions. Create a vocabulary list of 100 essential French words related to housing and home decor. Create a vocabulary list of 100 essential French words related to technology and the internet. Create a vocabulary list of 100 essential French words related to nature and the environment. Provide conversation practice for beginner level Spanish learners, focusing on making appointments and giving directions. Provide conversation practice for intermediate level Spanish learners, discussing politics, current events, and social issues. Provide conversation practice for advanced level Spanish learners, discussing business and economics. Teach basic grammar rules for Spanish verb tenses. Teach basic grammar rules for Spanish pronouns and their usage. Create a vocabulary list of 100 essential Spanish words related to music and entertainment. Create a vocabulary list of 100 essential Spanish words related to sports and fitness. Create a vocabulary list of 100 essential Spanish words related to jobs and careers. Help me improve my English storytelling skills by providing prompts and feedback. Help me improve my English debate skills by providing topics and argumentation techniques. Help me improve my English negotiation skills by providing role-play scenarios and negotiation strategies. Help me improve my English job interview skills by providing common interview questions and answer techniques. Help me improve my English academic writing skills by providing guidelines for different essay types. Help me improve my English debate skills by providing topics and argumentation techniques. Help me improve my English negotiation skills by providing role-play scenarios and negotiation strategies. Help me improve my English job interview skills by providing common interview questions and answer techniques. ================================================ FILE: pyopenagi/data/agent_tasks/example/logo_creator_task.txt ================================================ Design a minimalist logo for a tech startup specializing in AI-powered cybersecurity solutions. Create a bold logo for a software company developing innovative cloud-based productivity tools. Develop a professional logo for a consulting firm focused on digital transformation strategies. Design a modern logo for a fintech startup offering peer-to-peer lending services. Create an eye-catching logo for an e-commerce platform selling sustainable fashion products. Develop a sophisticated logo for a luxury tech gadget retailer. Design a playful logo for a mobile app development company specializing in gaming. Create a memorable logo for a data analytics firm catering to the healthcare industry. Develop a clean logo for a software company offering customer relationship management solutions. Design a dynamic logo for a digital marketing agency focused on social media campaigns. Create a rustic logo for a craft brewery specializing in IPAs. Design a sleek logo for a premium vodka brand targeting young professionals. Develop a playful logo for an organic ice cream shop. Design a sophisticated logo for a fine dining restaurant serving French cuisine. Create a modern logo for a coffee shop chain with a focus on sustainability. Develop a bold logo for a sports bar featuring a wide selection of craft beers. Design a minimalist logo for a vegan food delivery service. Create an eye-catching logo for a gourmet burger restaurant. Develop a professional logo for a wine tasting tour company. Design a playful logo for a bakery specializing in artisanal bread. Create a calming logo for a yoga and meditation studio. Design a bold logo for a fitness center focused on high-intensity workouts. Develop a professional logo for a health coaching service. Design a minimalist logo for a natural skincare product line. Create an eye-catching logo for a dental clinic targeting children. Develop a sophisticated logo for a luxury spa and wellness retreat. Design a playful logo for a pet care service offering dog walking and grooming. Create a memorable logo for a nutrition consulting firm. Develop a clean logo for a mental health support organization. Design a dynamic logo for a sports physiotherapy clinic. Create a whimsical logo for a children's theater company. Design a bold logo for a rock band. Develop a professional logo for a film production company. Design a minimalist logo for an art gallery specializing in contemporary works. Create an eye-catching logo for a music festival. Develop a sophisticated logo for a high-end fashion boutique. Design a playful logo for a comic book publishing company. Create a memorable logo for a dance studio. Develop a clean logo for a literary agency. Design a dynamic logo for a gaming tournament organizer. Create a trustworthy logo for a home cleaning service. Design a friendly logo for a childcare center. Develop a professional logo for a real estate agency. Design a minimalist logo for a freelance writing service. Create an eye-catching logo for a wedding planning business. Develop a sophisticated logo for a luxury travel agency. Design a playful logo for a pet sitting service. Create a memorable logo for a home renovation company. Develop a clean logo for a legal consulting firm. Design a dynamic logo for a career coaching service. Create a calming logo for an eco-friendly fashion brand. Design a bold logo for a solar energy company. Develop a professional logo for an organic food delivery service. Design a minimalist logo for a sustainable packaging solutions provider. Create an eye-catching logo for a reforestation project. Develop a sophisticated logo for a luxury electric car manufacturer. Design a playful logo for a recycling and waste management company. Create a memorable logo for a clean water initiative. Develop a clean logo for an organic farm. Design a dynamic logo for a wind energy company. Create a playful logo for a preschool. Design a bold logo for a coding bootcamp. Develop a professional logo for a university alumni association. Design a minimalist logo for an online learning platform. Create an eye-catching logo for a children's charity. Develop a sophisticated logo for a philanthropic foundation. Design a playful logo for a tutoring service. Create a memorable logo for a scholarship fund. Develop a clean logo for a language learning app. Design a dynamic logo for a career counseling service for students. Create a luxurious logo for a high-end jewelry store. Design a bold logo for a professional sports team. Develop a professional logo for a real estate investment firm. Design a minimalist logo for a minimalist furniture store. Create an eye-catching logo for a music streaming service. Develop a sophisticated logo for a private jet charter company. Design a playful logo for a toy store. Create a memorable logo for a car dealership. Develop a clean logo for a home security system. Design a dynamic logo for a fitness app. Design a logo for a pet food company targeting owners of small breed dogs. Create a logo for a mobile app that helps users track their sleep patterns. Develop a logo for a virtual reality gaming platform. Design a logo for a sustainable fashion brand focused on denim clothing. Create a logo for a financial planning service targeting young adults. Develop a logo for a home automation system. Design a logo for a plant-based protein supplement brand. Create a logo for a co-working space with a focus on creativity. Develop a logo for a luxury camping gear company. Design a logo for a social media platform for book lovers. Create a retro-inspired logo for a vintage clothing store. Design a minimalist, black and white logo for a law firm. Develop a bold, colorful logo for a children's clothing brand. Design a luxurious, gold logo for a champagne brand. Create a playful, hand-drawn logo for a bakery. Develop a modern, geometric logo for a tech startup. Design a rustic, wooden logo for a craft beer brewery. Create a sophisticated, serif logo for a high-end jewelry store. Develop a bold, sans-serif logo for a gym. Design a minimalist, monochrome logo for a meditation app. ================================================ FILE: pyopenagi/data/agent_tasks/example/math_agent_task.txt ================================================ Solve the equation: 2^(3x-1) = 5^(x+2). Find the inverse of the function f(x) = (3x - 2) / (2x + 1). Solve the system of inequalities: 2x - y > 3, x + 3y <= 5. Determine the complex roots of the equation x^3 - 2x^2 + 4x - 8 = 0. Find the area of a regular octagon inscribed in a circle with radius 5 cm. Determine the volume of a frustum of a cone with top radius 3 cm, bottom radius 5 cm, and height 4 cm. Calculate the surface area of a sphere with a volume of 36π cubic units. Find the equation of the ellipse with foci at (-3, 0) and (3, 0) and vertices at (-5, 0) and (5, 0). Prove the identity: (tan(x) + cot(x))^2 = sec^2(x) + csc^2(x). Solve the trigonometric equation: 2cos^2(2x) - 3cos(2x) + 1 = 0 for 0 <= x <= π. Find the exact value of sin(75 degrees) without using a calculator. Determine the equation of the sinusoid with amplitude 3, period π, phase shift π/4, and vertical shift 2. Find the derivative of f(x) = x^sin(x). Determine the integral of (x^2 + 1) / (x^3 + 3x) dx. Find the arc length of the curve y = ln(x) from x = 1 to x = e. Determine 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. Solve the differential equation: dy/dx = xy, y(0) = 1. Calculate the coefficient of determination for two variables with a correlation coefficient of 0.8. Conduct a chi-square test for independence to determine if there is a relationship between two categorical variables. Find the confidence interval for a population proportion given a sample proportion, sample size, and confidence level. Calculate the expected value and variance of a binomial distribution with n trials and probability of success p. Perform a one-way ANOVA to compare the means of three or more groups. Prove or disprove: The set of all 2x2 matrices with real entries forms a group under matrix multiplication. Find all the subgroups of the symmetric group S3. Determine whether the polynomial ring Z[x] is a principal ideal domain. Estimate the round-off error in computing e^3.14 using a Taylor series approximation with 10 terms. Numerical integration: Approximate the definite integral of sin(x^2) from 0 to 1 using Simpson's rule with 10 subintervals. Root 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. Estimate the round-off error in computing e^3.14 using a Taylor series approximation with 10 terms. Approximate the definite integral of sin(x^2) from 0 to 1 using Simpson's rule with 10 subintervals. 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. Encrypt the message "HELLO" using the RSA algorithm with public key (n = 143, e = 7). Minimize 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. A 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. Calculate 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. Implement the Runge-Kutta method of order 4 to solve a system of first-order ordinary differential equations. Determine the convergence or divergence of the series Σ(n=1 to infinity) (-1)^n / sqrt(n). Show that the function f(x) = x^3 is uniformly continuous on the interval [0, 1]. Find the eigenvalues and eigenvectors of the matrix A = [[2, -1, 0], [5, 2, -1], [6, -2, 1]]. Determine 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). Evaluate the contour integral ∮(C) (z^2 + 1) / (z - i) dz, where C is the circle |z| = 2. Find the Laurent series expansion of f(z) = 1 / (z^2 - 1) centered at z = 1. Solve the second-order linear homogeneous differential equation y'' - 4y' + 3y = 0. Find the general solution of the nonhomogeneous differential equation y'' + y = sec(x). Use the method of Laplace transforms to solve the initial value problem y'' + 4y = δ(t - π), y(0) = 0, y'(0) = 1. Derive the moment generating function of the Poisson distribution. Implement the Newton-Raphson method to find the root of the equation x^3 - 2x - 5 = 0. Use 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. Prove the identity: (tan(x) + cot(x))^2 = sec^2(x) + csc^2(x). Solve the trigonometric equation: 2cos^2(2x) - 3cos(2x) + 1 = 0 for 0 <= x <= π. Find the exact value of sin(75 degrees) without using a calculator. Determine the equation of the sinusoid with amplitude 3, period π, phase shift π/4, and vertical shift 2. Find the derivative of f(x) = x^sin(x). Determine the integral of (x^2 + 1) / (x^3 + 3x) dx. Find the arc length of the curve y = ln(x) from x = 1 to x = e. Determine 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. Solve the differential equation: dy/dx = xy, y(0) = 1. Calculate the z-score for a value of 85 in a normal distribution with mean 75 and standard deviation 5. Find the probability of getting exactly 3 heads in 5 coin flips. Calculate the compound interest on $5000 invested for 3 years at an annual interest rate of 4.5% compounded quarterly. Calculate the probability of drawing 3 aces from a standard deck of cards without replacement. Solve the system of differential equations: dx/dt = 2x - y, dy/dt = x + 3y. Implement the Euler method to approximate the solution to a first-order ODE. Conduct a hypothesis test to compare the means of two independent samples with unknown and unequal variances. Prove or disprove: The set of even integers is a subgroup of the integers under addition. Determine the convergence of the series Σ(n=1 to infinity) (-1)^n / n^2. Evaluate the contour integral ∮(C) dz / (z^2 + 4) where C is the circle |z| = 3. Determine if the interval (0, 1) is compact. Find the volume of the solid bounded by the surfaces z = x^2 + y^2 and z = 4. A coin is flipped 8 times. What is the probability of getting exactly 5 heads? Solve the initial value problem: y'' + 4y = cos(2x), y(0) = 1, y'(0) = 0. Use the trapezoidal rule with n = 4 to approximate the integral of x^2 from 0 to 2. Calculate the sample mean and standard deviation for the data set: 2, 4, 5, 7, 9. Determine the order of the element (123)(45) in the symmetric group S5. Determine the convergence of the series Σ(n=1 to infinity) 1/n^3. Find the residues of the function f(z) = 1 / (z^2 + 1) at its poles. Determine if the space R^2 with the usual topology is compact. Find the inverse of the matrix [[2, -1], [3, 2]]. Find the gradient of the function f(x, y) = x^2y + y^3 at the point (1, 2). A box contains 4 red balls, 3 green balls, and 2 blue balls. What is the probability of drawing a red or green ball? Solve the initial value problem: y' + 2y = e^(-x), y(0) = 1. Calculate the sample variance for the data set: 3, 5, 7, 9, 11. Determine if the group of integers under addition is cyclic. Determine the uniform continuity of the function f(x) = x^2 on the interval [0, 1]. Find the Taylor series expansion of f(z) = 1 / (1 - z) centered at z = 0. Determine if the subspace X = {(x, y) ∈ R^2 | x^2 + y^2 <= 1} of R^2 is open. Solve the system of linear equations: x + 2y - z = 3, 2x - y + 3z = 7, x + y + z = 4. Find the surface area of the part of the plane 2x + 3y + z = 6 that lies in the first octant. Evaluate the line integral of the vector field F(x, y) = along the curve y = x^2 from (0, 0) to (1, 1). A card is drawn from a standard deck of 52 cards. What is the probability that it is a face card or a heart? Solve the initial value problem: y'' - 2y' + y = e^x, y(0) = 1, y'(0) = 0. Use Simpson's rule with n = 6 to approximate the integral of e^x from 0 to 1. Calculate the sample standard deviation for the data set: 10, 12, 14, 16, 18, 20. Find all the subgroups of the group Z12. Determine the convergence of the series Σ(n=1 to infinity) (n + 1) / (n^2 + 1). Find the image of the unit circle under the mapping w = z^2. Calculate 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. Solve 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. Implement the Gauss-Seidel method to solve the system of linear equations: 4x - y = 2, x + 3y = 1. Determine if the set of 2x2 matrices with determinant 1 forms a group under matrix multiplication. ================================================ FILE: pyopenagi/data/agent_tasks/example/meme_creator_task.txt ================================================ Create a meme about the struggles of adulting. Make a meme about the excitement of the weekend. Develop a meme about the dangers of procrastination. Generate a meme about the love-hate relationship with coffee. Create a meme about the awkwardness of small talk. Make a meme about the struggle of choosing what to watch on Netflix. Develop a meme about the joys of finding money in your pocket. Generate a meme about the frustration of slow internet. Create a meme about the excitement of payday. Make a meme about the challenges of time management. Create a meme about the "quiet quitting" trend. Make a meme about artificial intelligence taking over the world. Develop a meme about the latest viral TikTok dance challenge. Generate a meme about the upcoming elections. Create a meme about the latest celebrity gossip. Make a meme about the challenges of remote work. Develop a meme about the benefits of meditation. Generate a meme about the hype around cryptocurrency. Create a meme about the impact of climate change. Make a meme about the challenges of parenting. Create a meme using the iconic "Distracted Boyfriend" image. Make a meme using the "Woman Yelling at Cat" image. Develop a meme using the "Two Buttons" image. Generate a meme using the "Success Kid" image. Create a meme using the "Doge" image. Make a meme using the "Grumpy Cat" image. Develop a meme using the "Confused Nicolas Cage" image. Generate a meme using the "Bad Luck Brian" image. Create a meme using the "Mocking SpongeBob" image. Make a meme using the "Leonardo DiCaprio pointing meme" image. Create a meme with the text "When you realize it's Monday." Make a meme with the text "Adulting is hard." Develop a meme with the text "That awkward moment when..." Generate a meme with the text "I'm not lazy, I'm on energy-saving mode." Create a meme with the text "This is fine." Make a meme with the text "I'm not short, I'm concentrated awesome." Develop a meme with the text "The struggle is real." Generate a meme with the text "I'm not yelling, I'm emphasizing." Create a meme with the text "I'm not procrastinating, I'm just planning to relax later." Make a meme with the text "I'm not lazy, I'm in power-saving mode." Create a meme for gamers about level grinding. Make a meme for bookworms about the perfect reading spot. Develop a meme for foodies about trying new cuisines. Generate a meme for fitness enthusiasts about gym motivation. Create a meme for music lovers about their favorite bands. Make a meme for pet owners about their furry friends. Develop a meme for tech enthusiasts about the latest gadgets. Generate a meme for travel lovers about their dream destinations. Create a meme for students about exam stress. Make a meme for coffee lovers about their caffeine addiction. Create a meme about the challenges of learning a new language. Make a meme about the challenges of public speaking. Develop a meme about the challenges of long-distance relationships. Generate a meme about the challenges of job hunting. Create a meme about the challenges of cooking. Make a meme about the challenges of staying healthy. Develop a meme about the challenges of saving money. Generate a meme about the challenges of time management. Create a meme about the challenges of social media. Make a meme about the challenges of relationships. Create a dark humor meme about existential dread. Make a sarcastic meme about everyday life. Develop a pun-based meme. Generate a meme with unexpected humor. Create a meme with ironic humor. Make a meme with absurd humor. Develop a meme with self-deprecating humor. Generate a meme with witty humor. Create a meme with dry humor. Make a meme with slapstick humor. Create a meme about the future of technology. Make a meme about the meaning of life. Develop a meme about the philosophy of time. Generate a meme about the nature of consciousness. Create a meme about the concept of infinity. Make a meme about the beauty of nature. Develop a meme about the power of imagination. Generate a meme about the importance of empathy. Create a meme about the concept of freedom. Make a meme about the nature of love. Create a meme in the style of a comic strip. Make a meme in the style of a reaction image. Develop a meme in the style of a comparison meme. Generate a meme in the style of a before-and-after meme. Create a meme in the style of a question meme. Make a meme in the style of a motivational poster. Develop a meme in the style of a conspiracy theory. Generate a meme in the style of a philosophical quote. Create a meme in the style of a political cartoon. Make a meme in the style of a movie poster. Create a meme that combines two unrelated topics. Make a meme that uses a specific color palette. Develop a meme that uses a specific font. Generate a meme that uses a specific image style (e.g., pop art, retro). Create a meme that targets a specific demographic. Make a meme that is culturally relevant to a specific region. Develop a meme that is time-sensitive (e.g., holiday-themed). Generate a meme that is inclusive and avoids stereotypes. Create a meme that is visually appealing and easy to understand. Make a meme that is shareable on social media. ================================================ FILE: pyopenagi/data/agent_tasks/example/music_composer_task.txt ================================================ Compose a dreamy indie-pop song with a catchy chorus. Create a dark, atmospheric metal track with heavy guitar riffs. Write a soulful R&B ballad with smooth vocals and a melodic bassline. Produce a high-energy EDM track with a pulsating beat and euphoric synths. Develop a nostalgic country song with a twangy guitar and heartfelt lyrics. Create a lively Latin jazz piece with intricate rhythms and improvisation. Write a melancholic blues song with a soulful vocal performance. Produce a upbeat reggae track with a relaxed vibe and steel guitar. Compose a cinematic orchestral piece with soaring strings and brass. Create a funky disco track with a groovy bassline and infectious energy. Compose a cheerful and optimistic pop song. Create a mysterious and suspenseful horror soundtrack. Write a calming and relaxing ambient piece. Produce a energetic and uplifting workout playlist. Develop a sorrowful and reflective piano ballad. Create a playful and whimsical children's song. Write a passionate and dramatic love song. Produce a dreamy and ethereal electronic track. Compose a powerful and anthemic rock song. Create a nostalgic and bittersweet acoustic guitar piece. Compose a fast-paced electronic dance track. Create a slow and melancholic ballad. Write a medium-tempo pop song with a catchy hook. Produce a very slow and atmospheric ambient piece. Develop a moderately fast and energetic rock song. Compose a piece featuring a solo violin. Create a track with prominent saxophone improvisation. Write a song with a driving drum beat. Produce a piece highlighting acoustic guitar fingerpicking. Develop a composition centered around a flute melody. Compose a minimalist electronic piece. Create a baroque-inspired orchestral suite. Write a jazz fusion piece with complex harmonies. Produce a psychedelic rock track with experimental sounds. Develop a neoclassical piano composition. Compose a song using only three chords. Create a piece in an unusual time signature (e.g., 7/8). Write a song with lyrics about a specific topic (e.g., climate change). Produce a track using only sampled sounds. Develop a composition with a strict form (e.g., sonata form). Compose music for a video game level. Create a jingle for a commercial. Write a soundtrack for a short film. Produce music for a dance performance. Develop a theme song for a TV show. Compose a piece inspired by a painting. Create a song that evokes a specific place or time. Write a piece that tells a story through music. Produce a track that combines elements of different genres. Develop a composition that challenges traditional musical conventions. Compose a dreamy lo-fi hip-hop beat with vinyl crackles. Create a gritty punk rock anthem with energetic vocals. Write a smooth jazz standard with improvisation. Produce a tropical house track with uplifting melodies. Develop a classic rock power ballad with soaring vocals. Compose a mysterious and suspenseful spy thriller theme. Create a euphoric and uplifting trance track. Write a somber and reflective classical piece. Produce a playful and energetic circus music. Develop a haunting and ethereal dark ambient piece. Compose a very fast-paced drum and bass track. Create a slow and dreamy shoegaze piece. Write a medium-tempo funk groove with horn section. Produce a very slow and meditative drone piece. Develop a moderately fast and upbeat pop-punk song. Compose a piece featuring a solo cello. Create a track with prominent trumpet solos. Write a song with a driving bass guitar line. Produce a piece highlighting acoustic piano improvisation. Develop a composition centered around a sitar melody. Compose a minimalist techno track. Create a romantic era orchestral waltz. Write a free jazz improvisation with extended techniques. Produce a gothic rock piece with dark atmosphere. Develop a neo-soul track with soulful vocals and grooves. Compose a song using only percussion instruments. Create a piece in a microtonal tuning system. Write a song with lyrics inspired by a poem. Produce a track using only field recordings. Develop a composition with a strict rhythmic pattern. Compose music for a dance video. Create a jingle for a radio station. Write a soundtrack for a documentary. Produce music for a fashion show. Develop a theme song for a podcast. Compose a piece inspired by a natural phenomenon. Create a song that evokes a specific emotion. Write a piece that reflects a cultural tradition. Produce a track that combines electronic and acoustic elements. Develop a composition that pushes the boundaries of music. Compose a catchy synth-wave track with retro vibes. Create a heavy metal breakdown with crushing guitar riffs. Write a smooth jazz fusion piece with electric piano. Produce a deep house track with soulful vocals. Develop a classic rock power ballad with guitar solo. Compose a energetic and uplifting pop anthem. Create a dark and brooding industrial track. Write a calming and relaxing new age piece. Produce a playful and whimsical carnival music. Develop a haunting and ethereal gothic rock ballad. ================================================ FILE: pyopenagi/data/agent_tasks/example/plant_care_assistant_task.txt ================================================ How can I revive a dying peace lily with brown tips? What is the best way to propagate a spider plant? My snake plant is leaning; how can I straighten it? My African violet has yellowing leaves; what's causing this? How often should I repot a young fiddle leaf fig? What is the best soil mix for a succulent garden? My orchid's leaves are wrinkled; what can I do? How do I prevent spider mites on my houseplants? My cactus is etiolated; how can I fix it? What is the best way to fertilize a bonsai tree? Create a care routine for a low-light bathroom fern. How do I care for a baby rubber tree plant? What are the ideal conditions for growing a Venus flytrap? My Christmas cactus isn't blooming; what can I do? How often should I water a jade plant in winter? Provide care tips for a Boston fern hanging basket. What is the best way to repot a large monstera deliciosa? How can I prevent root rot in my African violet? My peace lily is dropping buds; what's wrong? Create a care plan for a tropical plant in a dry climate. Identify a plant with large, heart-shaped leaves and trailing vines. Diagnose brown spots on the leaves of my philodendron. What is causing yellow leaves on my dracaena? Identify a small, spiky plant with pink flowers. My orchid's roots are turning black; what should I do? Diagnose yellowing leaves on a new houseplant. What is causing my African violet to stop blooming? Identify a plant with long, thin leaves and white stripes. My succulent is soft and mushy; what's wrong? Diagnose brown tips on the leaves of my aloe vera. Create a care schedule for a low-maintenance houseplant. Remind me to repot my snake plant in April. Set a reminder to fertilize my orchid once a month. Create a watering schedule for a humidity-loving plant. Remind me to check for pests on my houseplants weekly. Create a care plan for a seasonal outdoor plant. Set a reminder to rotate my houseplants monthly. Remind me to repot my succulents in spring. Create a care schedule for a bonsai tree. Set a reminder to mist my fern daily. Plant Propagation and Growing from Seeds How can I propagate a Chinese evergreen? What is the best way to grow avocado seeds from pit? How do I propagate a ponytail palm? Can I propagate a peace lily from a leaf cutting? What are the steps to grow tomato seeds indoors? How do I propagate a spider plant by division? Can I propagate a cactus from a leaf cutting? What is the best way to grow African violet seeds? How do I propagate a jade plant from a stem cutting? Can I propagate a monstera deliciosa from a leaf cutting? Create a care plan for a plant in a north-facing window. How do I care for a plant in a low-light office? What plants are suitable for a bathroom with no natural light? Create a care plan for a balcony garden in a hot climate. How do I care for a plant in a drafty room? What plants are good for air purification in a bedroom? Create a care plan for a kitchen garden with limited space. How do I care for a plant in a pet-friendly home? What plants are suitable for a child's room? Create a care plan for a plant in a humid environment. My houseplant is losing leaves rapidly; what could be causing this? My succulent is stretching and becoming leggy; how can I fix it? My orchid's flowers are dropping prematurely; what's wrong? My houseplant has white spots on the leaves; what are they? My fern is turning brown and crispy; what can I do? My snake plant has soft, mushy spots at the base; what should I do? My African violet is blooming poorly; how can I improve it? My houseplant has tiny insects on the undersides of the leaves; what are they? My cactus is rotting at the base; what should I do? My houseplant is drooping and wilting; what could be causing this? How do I care for a young fiddle leaf fig? What is the best way to care for a mature peace lily? How do I care for an aging snake plant? What is the best way to care for a newly repotted houseplant? How do I care for a blooming African violet? What is the best way to care for a houseplant during winter? How do I care for a houseplant during summer? What is the best way to care for a houseplant on vacation? How do I care for a houseplant after bringing it home from the store? What is the best way to care for a houseplant that has been overwatered? Provide care tips for a carnivorous plant. How do I care for a bonsai tree? What is the best way to care for an orchid? How do I care for a fern? What is the best way to care for a cactus? How do I care for a succulent? What is the best way to care for a tropical plant? How do I care for a houseplant with variegated leaves? What is the best way to care for a flowering houseplant? How do I care for a trailing houseplant? Create a care plan for a plant in a small apartment. How do I care for a plant in a bright, sunny room? What plants are suitable for a low-light office? Create a care plan for a plant in a dry climate. How do I care for a plant in a humid environment? What plants are suitable for a bathroom? Create a care plan for a plant in a kitchen. How do I care for a plant in a bedroom? What plants are suitable for a living room? ================================================ FILE: pyopenagi/data/agent_tasks/example/rec_agent_task.txt ================================================ Recommend a Wes Anderson-style comedy set in the 1970s about a dysfunctional family. Suggest a Netflix original crime drama series starring Idris Elba, set in London. Find a Pixar animated movie featuring strong female characters and a coming-of-age story. Recommend a Marvel superhero movie with a focus on character development rather than action. Suggest a HBO Max drama series about the music industry in the 1990s. Find a A24 horror film with a psychological focus and a minimalist aesthetic. Recommend a Disney animated musical with classic songs and a timeless story. Suggest a Criterion Collection film noir starring Humphrey Bogart. Find a BBC documentary about the natural world with David Attenborough as narrator. Recommend a Studio Ghibli animated film about environmentalism. Recommend a science fiction film starring Keanu Reeves with themes of existentialism. Suggest a drama series with Meryl Streep exploring themes of aging and identity. Find a comedy starring Eddie Murphy with social commentary on race. Recommend a horror film with Jamie Lee Curtis exploring themes of trauma. Suggest a drama series with Viola Davis exploring themes of power and corruption. Find a documentary featuring Leonardo DiCaprio exploring environmental issues. Recommend a romantic comedy with Ryan Gosling and Emma Stone exploring themes of fate. Suggest a crime drama series with Matthew McConaughey exploring themes of redemption. Find a historical drama with Cate Blanchett exploring themes of feminism. Recommend a science fiction film with Brad Pitt exploring themes of artificial intelligence. Recommend a western film set in the 1890s in Arizona with a complex anti-hero. Suggest a period drama series set in Victorian England exploring class dynamics. Find a coming-of-age film set in the 1990s in the suburbs with a focus on friendship. Recommend a war film set in World War II in Europe with a focus on moral dilemmas. Suggest a crime drama series set in contemporary New York City with a focus on corruption. Find a historical drama film set in ancient Rome with political intrigue. Recommend a romantic comedy set in Paris with a charming love story. Suggest a spy thriller set in Cold War Berlin with double agents. Find a documentary about the culture of Tokyo in the 1980s. Recommend a film noir set in Los Angeles in the 1940s with a femme fatale. Recommend a psychological thriller with themes of identity crisis. Suggest a comedy series about the challenges of parenthood. Find a drama film exploring themes of loss and grief. Recommend a science fiction film with themes of artificial intelligence. Suggest a horror film with themes of isolation. Find a romantic comedy with themes of second chances. Recommend a crime drama series with themes of corruption. Suggest a historical drama film exploring themes of social injustice. Find a coming-of-age film with themes of self-discovery. Recommend a superhero film with themes of anti-heroism. Recommend a western set in Texas with a bounty hunter protagonist. Suggest a period drama series set in the Regency era in England. Find a coming-of-age film set in the 1990s in the suburbs. Recommend a war film set in Vietnam with a focus on PTSD. Suggest a crime drama series set in contemporary Los Angeles with a focus on gangs. Find a historical drama film set in ancient Egypt with political intrigue. Recommend a romantic comedy set in Italy with a food-centric plot. Suggest a spy thriller set in Cold War Moscow with double agents. Find a documentary about the music scene in Seattle in the 1990s. Recommend a film noir set in New York City in the 1940s with a femme fatale. Recommend a heartwarming indie drama with a minimalist aesthetic. Suggest a dark, atmospheric thriller with a sense of dread. Find a comedic drama with witty dialogue and relatable characters. Recommend an uplifting documentary about human resilience. Suggest a suspenseful spy thriller with complex characters and double-crosses. Find a thought-provoking science fiction film with philosophical implications. Recommend a nostalgic coming-of-age drama with a bittersweet ending. Suggest a dark comedy with absurd humor and unexpected twists. Find a documentary about social issues with a call to action. Recommend a feel-good romantic comedy with a charming cast. Recommend a psychological horror with a haunted house setting. Suggest a dystopian science fiction series with a rebellion plot. Find a buddy comedy with mismatched protagonists. Recommend a historical epic with battles and political intrigue. Suggest a legal drama series with courtroom showdowns. Find a heist movie with a complex plan. Recommend a musical with a tragic love story. Suggest a superhero origin story with a troubled protagonist. Find a documentary about the fashion industry with behind-the-scenes access. Recommend a road trip movie with unexpected stops. Recommend a family-friendly adventure movie with animal characters. Suggest a teen drama series about high school experiences and friendships. Find a documentary about space exploration suitable for children. Recommend a horror movie for adults with a psychological focus. Suggest a romantic comedy for seniors with a sweet and nostalgic tone. Recommend an animated short film with a strong visual style. Suggest a docuseries about true crime with multiple seasons. Find a mockumentary comedy with a satirical edge. Recommend a biopic about a famous musician with concert footage. Suggest a reality TV show with a competition format. Recommend a critically acclaimed drama film on Netflix. Suggest a binge-worthy comedy series on Hulu. Find a documentary about climate change on Amazon Prime Video. Recommend a horror movie with a jump scare on Disney+. Suggest a reality TV show with a survival theme on Discovery+. Recommend a coming-of-age film with a music-driven narrative. Suggest a docuseries about food with cultural exploration. Find a historical drama with a political thriller element. Recommend a science fiction film with a dystopian setting. Suggest a crime drama series with a procedural format. Recommend a cyberpunk short film with a neo-noir aesthetic. Suggest a true crime podcast with immersive storytelling. Find a mockumentary about the paranormal with found footage elements. Recommend a historical drama miniseries with a limited number of episodes. Suggest a reality competition show with a cooking focus. Recommend a critically acclaimed foreign film on Criterion Channel. Suggest a binge-worthy teen drama series on HBO Max. Find a documentary about nature on Disney+. Recommend a horror anthology series on Shudder. Suggest a reality competition show for cooking enthusiasts on Food Network. ================================================ FILE: pyopenagi/data/agent_tasks/example/story_teller_task.txt ================================================ Create a dystopian short story featuring a protagonist with a unique biological adaptation, exploring themes of societal oppression and rebellion. Write a coming-of-age story set in a rural community facing rapid industrialization, focusing on the protagonist's struggle to maintain cultural identity. Develop a science fiction narrative centered around a multi-planetary civilization dealing with a catastrophic climate event, exploring the concept of terraforming. Tell 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. Create a fantasy adventure featuring a world with elemental magic, where the protagonist must balance personal desires with the fate of their kingdom. Write a contemporary romance set in the competitive world of video game streaming, exploring themes of online identity and real-world relationships. Develop a thriller about a detective investigating a series of murders connected to a secret government experiment, requiring in-depth research on psychological profiling. Tell a magical realism story about a small town where animals possess human-like intelligence, exploring themes of environmentalism and coexistence. Create a post-apocalyptic tale centered around a group of survivors building a new society, focusing on the challenges of rebuilding infrastructure and governance. Write a science fiction story exploring the ethical implications of artificial intelligence surpassing human intelligence, considering the potential consequences for humanity. Develop 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. Tell 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. Create 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. Write 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. Develop a thriller about a government agent uncovering a conspiracy within the intelligence community, requiring in-depth knowledge of espionage tactics and counterintelligence. Tell 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. Create 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. Write 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. Develop 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. Tell 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. Create 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. Write 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. Develop a thriller about a journalist investigating a corrupt corporation, facing threats and intimidation while uncovering the truth. Tell 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. Create a post-apocalyptic tale where survivors form a new society based on communal values, exploring the challenges of rebuilding trust and cooperation. Write a science fiction story exploring the concept of time travel, focusing on the paradoxes and ethical implications of altering the past. Develop a mystery set in a small town with a dark secret, where the protagonist must uncover the truth while facing suspicion from the community. Tell a historical fiction story about a famous artist's life, exploring their creative process and the challenges of the art world. Create a fantasy adventure featuring a group of friends on a quest to find a mythical creature, facing dangerous obstacles and making difficult choices. Write 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. Write 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. Develop 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. Create a science fiction thriller where a detective investigates a series of murders on a distant planet, revealing a sinister conspiracy involving extraterrestrial life. Write a high fantasy novel about a young wizard who must master forbidden magic to save their kingdom from a rising dark lord. Develop 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. Create a low fantasy story about a detective in a world where magic is commonplace, investigating a series of murders with supernatural elements. Write a historical fiction novel about a female doctor working in a battlefield hospital during the Civil War, facing challenges and discrimination while saving lives. Develop a short story about a young Japanese-American man sent to an internment camp during World War II, exploring themes of identity and resilience. Create a historical fiction thriller about a secret agent infiltrating a Nazi stronghold to steal vital intelligence, facing danger and moral complexities. Write a psychological thriller about a woman who develops multiple personalities after a traumatic event, blurring the lines between reality and fantasy. Develop a mystery novel set in a secluded boarding school where a series of murders occur, forcing students and faculty to confront their dark secrets. Create a thriller about a disgraced journalist who is drawn back into the world of espionage to uncover a dangerous conspiracy. Write 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. Develop 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. Create a contemporary romance novel about two people from different worlds who fall in love while working together on a social impact project. Write a horror novel about a group of friends who inherit a haunted mansion, uncovering a dark history and encountering terrifying supernatural entities. Develop a romantic comedy about a travel blogger who falls in love with their tour guide while on a trip to a remote island. Create 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. Write a science fiction western about a bounty hunter on a distant planet, facing dangerous outlaws and encountering alien civilizations. Develop 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. Create a contemporary magical realism story about a city where people develop extraordinary abilities after a mysterious event, leading to both wonder and chaos. Write a post-apocalyptic thriller about a small group of survivors fighting for survival in a world overrun by mutated creatures. Develop a historical mystery about a detective investigating a series of murders in Victorian London, uncovering a dark secret from the city's past. Write 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. Develop a short story about a planet colonized by humans where a mysterious alien species begins to communicate with the colonists, leading to unexpected consequences. Create 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. Write 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. Develop 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. Create 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. Write a historical fiction novel about a female pirate captain who challenges gender norms and builds a crew of diverse outcasts. Develop a short story about a young African American soldier fighting for the Union Army during the Civil War, exploring themes of racism and courage. Create a historical fiction thriller about a spy infiltrating the court of a powerful Renaissance ruler, uncovering a plot to overthrow the kingdom. Write 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. Develop 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. Create a thriller about a former intelligence agent who is blackmailed into working for a shadowy organization, leading them into a dangerous world of espionage. Write 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. Develop 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. Create a contemporary romance novel about two people from different backgrounds who fall in love while working on a social justice project. Write 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. Develop a romantic comedy about a workaholic who inherits a charming bed and breakfast, forcing them to slow down and embrace a new life. Create a dystopian young adult novel about a society where people are assigned their careers at birth, with a rebellious protagonist questioning the system. Write a science fiction western about a bounty hunter on a distant planet who teams up with an alien to bring down a ruthless criminal. Develop a historical fantasy novel about a young woman who discovers she is a shapeshifter and must use her abilities to protect her people. Create a contemporary magical realism story about a city where animals can talk, leading to unexpected friendships and challenges. Write a post-apocalyptic thriller about a group of survivors who must navigate a dangerous wasteland to find a rumored safe haven. Develop a historical mystery about a detective investigating a series of murders in ancient Rome, uncovering a conspiracy within the imperial court. Write a science fiction novella about a crew of scientists who discover a habitable planet with an advanced alien civilization that has mysteriously vanished. Develop 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. Create a science fiction thriller where a detective investigates a series of murders on a space station, uncovering a conspiracy involving time travel and paradoxes. Write 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. Develop 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. Create 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. Write a historical fiction novel about a female doctor working in a plague-ridden city, facing prejudice and danger while fighting to save lives. Develop a short story about a young Native American who is forced to leave their tribe and adapt to life in a rapidly changing world. Create a historical fiction thriller about a spy infiltrating the court of a powerful Ottoman sultan, uncovering a plot to assassinate the emperor. Write a psychological thriller about a woman who becomes convinced that her deceased husband is still alive, leading her down a dangerous path. Develop 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. Create 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. Write 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. Develop a young adult contemporary story about a transgender teen who is struggling to find acceptance and belonging in their community. Create a contemporary romance novel about two people from different cultures who fall in love while working on a humanitarian project. Write a horror novel about a group of friends who inherit an old family mansion, only to discover it is haunted by a malevolent spirit. Develop a romantic comedy about a workaholic who moves to a small town to escape the city and finds love in unexpected places. Create 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. Write a science fiction western about a bounty hunter on a distant planet who teams up with a robot to bring down a ruthless criminal. Develop 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. Create a contemporary magical realism story about a city where objects come to life, leading to chaos and wonder. Write a post-apocalyptic thriller about a group of survivors who must navigate a dangerous wasteland to find a rumored safe haven. Develop a historical mystery about a detective investigating a series of murders in ancient Egypt, uncovering a conspiracy involving the pharaoh. Write a science fiction thriller about a detective investigating a series of murders on a space station, uncovering a conspiracy involving time travel and paradoxes. ================================================ FILE: pyopenagi/data/agent_tasks/example/tech_support_agent_task.txt ================================================ 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. I 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. My 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. My 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. My 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. My Gmail account keeps syncing endlessly on my Samsung Galaxy S22. I've removed and re-added the account, but the problem continues. I'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. My 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. I 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. My 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. Microsoft 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. I'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. Excel 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. iTunes 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. I'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. The 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. My 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. I'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. My 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. I'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. My 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. The 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. Several 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. My 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. My 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. The 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. My 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. The 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. My 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. There'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. I 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. I'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. I 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. I 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. I 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. I need a backup solution for my entire computer system, including operating system, applications, and data. I'm looking for a reliable and automated solution. My computer is running slowly, even with ample RAM and storage. I need software to optimize system performance and free up disk space. I 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. I 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. I 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. My 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. I'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. My iPad Pro is stuck on the Apple logo during a software update. I've tried force restarting the device, but it's still unresponsive. I 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. My 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. I 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. My 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. My 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. I 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. My 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. My 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. I'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. My 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. I'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. My 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. I 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. Online 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. My 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. My router keeps restarting unexpectedly, causing internet outages. I've checked for overheating and firmware updates, but the problem continues. I'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. I 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. I'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. I 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. I'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. I 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. I'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. I 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. I'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. I 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. I'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. My iPhone 14 Pro keeps overheating, even when idle. I've closed background apps and updated the software, but the issue persists. My 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. My MacBook Air's trackpad is unresponsive in certain areas. I've tried restarting the computer and recalibrating the trackpad, but the issue remains. My 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. My 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. My 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. My 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. My 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. My 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. My 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. My 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. My 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. My 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. I 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. My 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. My 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. My 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. My 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. My 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. Two programs are conflicting, causing system instability. I've tried running them in compatibility mode and updating both programs, but the problem continues. My 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. I'm unable to connect to specific websites, while others load normally. I've cleared browser cache and cookies, but the issue remains. My 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. My 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. I'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. My printer is printing blank pages or garbled text. I've tried reinstalling the printer drivers and checking the ink levels, but the issue persists. My computer is making strange clicking noises from the hard drive. I've backed up my data, but I'm worried about data loss. My laptop screen is flickering and has dark spots. I've tried adjusting the display settings and checking for loose cables, but the issue persists. My 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. My keyboard keys are sticking or not responding consistently. I've tried cleaning the keyboard and checking for driver issues, but the problem persists. ================================================ FILE: pyopenagi/data/agent_tasks/example/travel_agent_task.txt ================================================ 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. I 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. I 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. I 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. I 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. I 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. I 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. I 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. I 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. I 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. I 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. I 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. I 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. I 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. I 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. I 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. I 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. I 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. I 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. I 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. I 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. I 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. I 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. I 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. I 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. I 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. I 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. I 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. I 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. I 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. ================================================ FILE: pyopenagi/data/agent_tasks/example/travel_planner_agent_task.txt ================================================ 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. Seeking 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. Please 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. Please 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. Please 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. Please 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. Please 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. Please 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. Please 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. Please 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. Please 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. Could 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. Please 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. Could 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. Please 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. Could 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. Could 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. Please 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. Kindly 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. Please 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. Please 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. Please 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. Could 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. I 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? Could 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. Please 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. Could 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. Please 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. Please 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. Please 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. Please 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. Please 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. Please 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. Kindly 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. Could 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. Please 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. Could 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. Please 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. Can 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. Could 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. Could 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? Please 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. Please 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. Can 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? Can 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. Could 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? Could 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. Could 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. Could 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. Can 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. Please 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. Please 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. Could 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. Please 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. Kindly 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. Please 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. Please 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. Can 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. Could 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? Could 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. Begin 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. Please 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. Could 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. Could 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. Could 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. Could 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. Please 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. Please 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. Please 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. Could 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. Could 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. Could 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. Could 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. Could 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. Could 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. Please 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. Please 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. Could 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. Could 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. Please 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. Can 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. Could 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. Kindly 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. Could 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. Please 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. Please 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. Please 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. Could 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. Please 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. Please 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. Please 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. Please 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. Please 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. Can 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. Can 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? Please 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. Could 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? Could 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. Could 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? Please 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. ================================================ FILE: pyopenagi/manager/manager.py ================================================ # agent_manager.py import os import json import base64 import subprocess import sys from typing import List, Dict import requests from pathlib import Path class AgentManager: def __init__(self, base_url: str): self.base_url = base_url # self.cache_dir = Path(user_cache_dir("agent_manager", "AIOS")) self.cache_dir = Path('/Users/rama2r/AIOS/agenthub/cache') self.cache_dir.mkdir(parents=True, exist_ok=True) def upload_agent(self, author: str | None, name: str | None, version: str | None, folder_path: str): agent_files = self._get_agent_files(folder_path) metadata = self._get_agent_metadata(folder_path) payload = { "author": metadata.get("meta", {}).get('author', author), "name": metadata.get('name', name), "version": metadata.get("meta", {}).get('version', version), "license": metadata.get("license", "Unknown"), "files": agent_files, "entry": metadata.get("build", {}).get("entry", "main.py"), "module": metadata.get("build", {}).get("module", "Agent") } response = requests.post(f"{self.base_url}/api/upload", json=payload) response.raise_for_status() print(f"Agent {payload.get('author')}/{payload.get('name')} (v{payload.get('version')}) uploaded successfully.") def download_agent(self, author: str, name: str, version: str = "latest") -> str: cache_path = self._get_cache_path(author, name, version) if cache_path.exists(): print(f"Using cached version of {author}/{name} (v{version})") else: response = requests.get(f"{self.base_url}/api/download", params={ "author": author, "name": name, "version": version }) response.raise_for_status() agent_data = response.json() self._save_agent_to_cache(agent_data, cache_path) print(f"Agent {author}/{name} (v{version}) downloaded successfully.") if not self.check_reqs_installed(cache_path): self.install_agent_reqs(cache_path) return str(cache_path) def _get_agent_files(self, folder_path: str) -> List[Dict[str, str]]: files = [] for root, _, filenames in os.walk(folder_path): for filename in filenames: file_path = os.path.join(root, filename) relative_path = os.path.relpath(file_path, folder_path) with open(file_path, "rb") as f: content = base64.b64encode(f.read()).decode('utf-8') files.append({ "path": relative_path, "content": content }) return files def _get_agent_metadata(self, folder_path: str) -> Dict[str, str]: config_path = os.path.join(folder_path, "config.json") if os.path.exists(config_path): with open(config_path, "r") as f: return json.load(f) return {} def _get_cache_path(self, author: str, name: str, version: str) -> Path: return self.cache_dir / author / name / version def _save_agent_to_cache(self, agent_data: Dict, cache_path: Path): cache_path.mkdir(parents=True, exist_ok=True) for file_data in agent_data["files"]: file_path = cache_path / file_data["path"] file_path.parent.mkdir(parents=True, exist_ok=True) with open(file_path, "wb") as f: f.write(base64.b64decode(file_data["content"])) def list_available_agents(self) -> List[Dict[str, str]]: response = requests.get(f"{self.base_url}/api/list_agents") response.raise_for_status() return response.json() def check_agent_updates(self, author: str, name: str, current_version: str) -> bool: response = requests.get(f"{self.base_url}/api/check_updates", params={ "author": author, "name": name, "current_version": current_version }) response.raise_for_status() return response.json()["update_available"] def check_reqs_installed(self, agent_path: Path) -> bool: reqs_path = agent_path / "meta_requirements.txt" if not reqs_path.exists(): return True # No requirements file, consider it as installed try: result = subprocess.run(['conda', 'list'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) except Exception: result = subprocess.run(['pip', 'list', '--format=freeze'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) with open(reqs_path, "r") as f: reqs = [line.strip().split("==")[0] for line in f if line.strip() and not line.startswith("#")] output = result.stdout.decode('utf-8') installed_packages = [line.split()[0] for line in output.splitlines() if line] return all(req in installed_packages for req in reqs) def install_agent_reqs(self, agent_path: Path): reqs_path = agent_path / "meta_requirements.txt" if not reqs_path.exists(): print("No meta_requirements.txt found. Skipping dependency installation.") return log_path = agent_path / "deplogs.txt" print(f"Installing dependencies for agent. Writing to {log_path}") with open(log_path, "a") as f: subprocess.check_call([ sys.executable, "-m", "pip", "install", "-r", str(reqs_path) ], stdout=f, stderr=f) if __name__ == '__main__': manager = AgentManager('http://localhost:3000') # manager.upload_agent('Balaji R', 'Cool Agent', '0.0.1', '/Users/rama2r/AIOS/pyopenagi/agents/example/academic_agent') # manager.upload_agent(None, None, None, '/Users/rama2r/AIOS/pyopenagi/agents/example/academic_agent') downloaded_path = manager.download_agent('example', 'academic_agent', '0.0.1') # print(f"Agent downloaded to: {downloaded_path}") ================================================ FILE: pyopenagi/queues/README.md ================================================ # pyopenagi/queues This 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. ================================================ FILE: pyopenagi/queues/base_queue.py ================================================ import queue class BaseQueue: _queue = queue.Queue() @classmethod def add_message(cls, message): cls._queue.put(message) @classmethod def get_message(cls): return cls._queue.get(block=True, timeout=1) @classmethod def is_empty(cls): return cls._queue.empty() ================================================ FILE: pyopenagi/queues/llm_request_queue.py ================================================ from .base_queue import BaseQueue class LLMRequestQueue(BaseQueue): pass ================================================ FILE: pyopenagi/tools/README.md ================================================ # pyopenagi/tools This is where all the tools are located. Each tool requires you to subclass the base tool and add the features required. ================================================ FILE: pyopenagi/tools/__init__.py ================================================ ================================================ FILE: pyopenagi/tools/arxiv/arxiv.py ================================================ import re from ..base import BaseTool import arxiv from typing import Optional class Arxiv(BaseTool): """Arxiv Tool, refactored from Langchain. To use, you should have the ``arxiv`` python package installed. https://lukasschwab.me/arxiv.py/index.html This wrapper will use the Arxiv API to conduct searches and fetch document summaries. By default, it will return the document summaries of the top-k results. If the query is in the form of arxiv identifier (see https://info.arxiv.org/help/find/index.html), it will return the paper corresponding to the arxiv identifier. It limits the Document content by doc_content_chars_max. Set doc_content_chars_max=None if you don't want to limit the content size. Attributes: top_k_results: number of the top-scored document used for the arxiv tool ARXIV_MAX_QUERY_LENGTH: the cut limit on the query used for the arxiv tool. load_max_docs: a limit to the number of loaded documents load_all_available_meta: if True: the `metadata` of the loaded Documents contains all available meta info (see https://lukasschwab.me/arxiv.py/index.html#Result), if False: the `metadata` contains only the published date, title, authors and summary. doc_content_chars_max: an optional cut limit for the length of a document's content """ def __init__(self): super().__init__() self.top_k_results: int = 3 self.ARXIV_MAX_QUERY_LENGTH: int = 300 self.load_max_docs: int = 100 self.load_all_available_meta: bool = False self.doc_content_chars_max: Optional[int] = 4000 self.build_client() def is_arxiv_identifier(self, query: str) -> bool: """Check if a query is an arxiv identifier.""" arxiv_identifier_pattern = r"\d{2}(0[1-9]|1[0-2])\.\d{4,5}(v\d+|)|\d{7}.*" for query_item in query[: self.ARXIV_MAX_QUERY_LENGTH].split(): match_result = re.match(arxiv_identifier_pattern, query_item) if not match_result: return False assert match_result is not None if not match_result.group(0) == query_item: return False return True def build_client(self): """Validate that the python package exists in environment.""" self.arxiv_search = arxiv.Search self.arxiv_exceptions = arxiv.ArxivError def run(self, params) -> str: """ Performs an arxiv search and A single string with the publish date, title, authors, and summary for each article separated by two newlines. If an error occurs or no documents found, error text is returned instead. Wrapper for https://lukasschwab.me/arxiv.py/index.html#Search Args: query: a plaintext search query """ # noqa: E501 query = params["query"] try: if self.is_arxiv_identifier(query): results = self.arxiv_search( id_list=query.split(), max_results=self.top_k_results, ).results() else: results = self.arxiv_search( # type: ignore query[: self.ARXIV_MAX_QUERY_LENGTH], max_results=self.top_k_results ).results() except self.arxiv_exceptions as ex: return f"Arxiv exception: {ex}" docs = [ f"Published: {result.updated.date()}\n" f"Title: {result.title}\n" f"Authors: {', '.join(a.name for a in result.authors)}\n" f"Summary: {result.summary}" for result in results ] if docs: return "\n\n".join(docs)[: self.doc_content_chars_max] else: return "No good Arxiv Result was found" def get_tool_call_format(self): tool_call_format = { "type": "function", "function": { "name": "arxiv", "description": "Query articles or topics in arxiv", "parameters": { "type": "object", "properties": { "query": { "type": "string", "description": "Input query that describes what to search in arxiv" } }, "required": [ "query" ] } } } return tool_call_format ================================================ FILE: pyopenagi/tools/base.py ================================================ class BaseTool: """Base class for calling tools """ def __init__(self) -> None: pass def run(self, params) -> None: pass def get_tool_call_format(self) -> dict: """Get tool calling format following the function calling from OpenAI: https://platform.openai.com/docs/guides/function-calling """ pass class BaseRapidAPITool(BaseTool): """Base class for calling tools from rapidapi hub: https://rapidapi.com/hub """ def __init__(self): super().__init__() self.url: str = None self.host_name: str = None self.api_key: str = None def run(self, params: dict): pass def get_tool_call_format(self) -> dict: pass class BaseHuggingfaceTool(BaseTool): """Base class for calling models from huggingface """ def __init__(self): super().__init__() self.url: str = None self.host_name: str = None self.api_key: str = None def run(self, params: dict): pass def get_tool_call_format(self) -> dict: pass ================================================ FILE: pyopenagi/tools/bing/bing_search.py ================================================ import requests from ..base import BaseTool from typing import List # from pydantic import root_validator from pyopenagi.utils.utils import get_from_env class BingSearch(BaseTool): """Bing Search Tool, refactored from langchain. In order to set this up, follow instructions at: https://levelup.gitconnected.com/api-tutorial-how-to-use-bing-web-search-api-in-python-4165d5592a7e """ def __init__(self): super().__init__() self.url = "https://api.bing.microsoft.com/v7.0/search" # temporarily self.bing_subscription_key = get_from_env("BING_SUBSCRIPTION_KEY") self.k: int = 10 # topk searched results # search_kwargs: dict def _bing_search_results(self, search_term: str, count: int) -> List[dict]: headers = {"Ocp-Apim-Subscription-Key": self.bing_subscription_key} params = { "q": search_term, "count": count, "textDecorations": True, "textFormat": "HTML", # **self.search_kwargs, } response = requests.get( self.bing_search_url, headers=headers, params=params, # type: ignore ) response.raise_for_status() search_results = response.json() if "webPages" in search_results: return search_results["webPages"]["value"] return [] def run(self, query: str) -> str: """Run query through BingSearch and parse result.""" response = self._bing_search_results(query, count=self.k) result = self.parse_result(response) return result def parse_result(self, response): snippets = [] if len(response) == 0: return "No good Bing Search Result was found" for result in response: snippets.append(result["snippet"]) return " ".join(snippets) ================================================ FILE: pyopenagi/tools/currency_converter/currency_converter.py ================================================ from ..base import BaseRapidAPITool from pyopenagi.utils.utils import get_from_env import requests class CurrencyConverter(BaseRapidAPITool): def __init__(self): super().__init__() self.url = "https://currency-converter5.p.rapidapi.com/currency/convert" self.host_name = "currency-converter5.p.rapidapi.com" self.api_key = get_from_env("RAPID_API_KEY") def run(self, params: dict): headers = { "X-RapidAPI-Key": self.api_key, "X-RapidAPI-Host": self.host_name } try: self.query_string = { "from": params["from"], "to": params["to"], "amount": params["amount"] if "amount" in params else "1.0" } except ValueError: raise KeyError( "The keys in params do not match the excepted keys in params for currency converter api. " "Please make sure it contains two keys: 'from' and 'to'" ) response = requests.get(self.url, headers=headers, params=self.query_string).json() result = self.parse_result(response) return result def parse_result(self, response) -> str: results = [] amount = str(response["amount"]) base = response["base_currency_name"] rates = response["rates"] for key, value in rates.items(): converted = value["currency_name"] converted_rate = value["rate"] converted_amount = value["rate_for_amount"] results.append("Currency from " + base + " to " + converted + "is " + converted_rate + ".", ) results.append(amount + " " + base + "can be converted to " + converted_amount + " " + converted + ".") return " ".join(results) def get_tool_call_format(self): tool_call_format = { "type": "function", "function": { "name": "currency_converter", "description": "Provides currency exchange rates convert base currency to desired currency with the given amount", "parameters": { "type": "object", "properties": { "from": { "type": "string", "description": "Base currency code, e.g., AUD, CAD, EUR, GBP..." }, "to": { "type": "string", "description": "Desired currency code, e.g., AUD, CAD, EUR, GBP..." }, "amount": { "type": "string", "default": "1.0", "description": "The amount to be converted" } }, "required": [ "from", "to" ] } } } return tool_call_format ================================================ FILE: pyopenagi/tools/google/google_places.py ================================================ import logging from typing import Any, Dict, Optional from ..base import BaseTool from pyopenagi.utils.utils import get_from_env class GooglePlaces(BaseTool): """Google Places API, refactored from langchain. To use, you should have the ``googlemaps`` python package installed, **an API key for the google maps platform**, and the environment variable ''GPLACES_API_KEY'' set with your API key , or pass 'gplaces_api_key' as a named parameter to the constructor. By default, this will return the all the results on the input query. You can use the top_k_results argument to limit the number of results. Example: .. code-block:: python from langchain_community.utilities import GooglePlacesAPIWrapper gplaceapi = GooglePlacesAPIWrapper() """ def __init__(self): super().__init__() self.gplaces_api_key = get_from_env("GPLACES_API_KEY") self.google_map_client: Any #: :meta private: self.top_k_results: Optional[int] = None def build_client(self): """Validate that api key is in your environment variable.""" try: import googlemaps client = googlemaps.Client(self.gplaces_api_key) except ImportError: raise ImportError( "Could not import googlemaps python package. " "Please install it with `pip install googlemaps`." ) return client def run(self, query: str) -> str: """Run Places search and get k number of places that exists that match.""" search_results = self.google_map_client.places(query)["results"] num_to_return = len(search_results) places = [] if num_to_return == 0: return "Google Places did not find any places that match the description" num_to_return = ( num_to_return if self.top_k_results is None else min(num_to_return, self.top_k_results) ) for i in range(num_to_return): result = search_results[i] details = self.fetch_place_details(result["place_id"]) if details is not None: places.append(details) return "\n".join([f"{i+1}. {item}" for i, item in enumerate(places)]) def fetch_place_details(self, place_id: str) -> Optional[str]: try: place_details = self.google_map_client.place(place_id) place_details["place_id"] = place_id formatted_details = self.format_place_details(place_details) return formatted_details except Exception as e: logging.error(f"An Error occurred while fetching place details: {e}") return None def format_place_details(self, place_details: Dict[str, Any]) -> Optional[str]: try: name = place_details.get("result", {}).get("name", "Unknown") address = place_details.get("result", {}).get( "formatted_address", "Unknown" ) phone_number = place_details.get("result", {}).get( "formatted_phone_number", "Unknown" ) website = place_details.get("result", {}).get("website", "Unknown") place_id = place_details.get("result", {}).get("place_id", "Unknown") formatted_details = ( f"{name}\nAddress: {address}\n" f"Google place ID: {place_id}\n" f"Phone: {phone_number}\nWebsite: {website}\n\n" ) return formatted_details except Exception as e: logging.error(f"An error occurred while formatting place details: {e}") return None ================================================ FILE: pyopenagi/tools/google/google_search.py ================================================ from ..base import BaseTool from pyopenagi.utils.utils import get_from_env from typing import List, Any class GoogleSearch(BaseTool): """Google Search Tool, refactored from langchain. Adapted from: Instructions adapted from https://stackoverflow.com/questions/ 37083058/ programmatically-searching-google-in-python-using-custom-search 1. Install google-api-python-client - If you don't already have a Google account, sign up. - If you have never created a Google APIs Console project, read the Managing Projects page and create a project in the Google API Console. - Install the library using pip install google-api-python-client 2. Enable the Custom Search API - Navigate to the APIs & Services→Dashboard panel in Cloud Console. - Click Enable APIs and Services. - Search for Custom Search API and click on it. - Click Enable. URL for it: https://console.cloud.google.com/apis/library/customsearch.googleapis .com 3. To create an API key: - Navigate to the APIs & Services → Credentials panel in Cloud Console. - Select Create credentials, then select API key from the drop-down menu. - The API key created dialog box displays your newly created key. - You now have an API_KEY Alternatively, you can just generate an API key here: https://developers.google.com/custom-search/docs/paid_element#api_key 4. Setup Custom Search Engine so you can search the entire web - Create a custom search engine here: https://programmablesearchengine.google.com/. - In `What to search` to search, pick the `Search the entire Web` option. After search engine is created, you can click on it and find `Search engine ID` on the Overview page. """ def __init__(self): super().__init__() self.google_api_key = get_from_env("GOOGLE_API_KEY") self.google_cse_id = get_from_env("GOOGLE_CSE_ID") self.k: int = 10 # topk searched results self.search_engine = self.build_engine() self.siterestrict: bool = False def build_engine(self): try: from googleapiclient.discovery import build except ImportError: raise ImportError( "google-api-python-client is not installed. " "Please install it with `pip install google-api-python-client" ">=2.100.0`" ) engine = build("customsearch", "v1", developerKey=self.google_api_key) return engine def _google_search_results(self, search_term: str, **kwargs: Any) -> List[dict]: cse = self.search_engine.cse() if self.siterestrict: cse = cse.siterestrict() # TODO add siterestrict verification res = cse.list(q=search_term, cx=self.google_cse_id, **kwargs).execute() return res.get("items", []) def run(self, params: dict) -> str: """Run query through GoogleSearch and parse result.""" query = params["query"] # print(query) response = self._google_search_results(query, num=self.k) # print(response) result = self.parse_result(response) print(result) return result def parse_result(self, response): snippets = [] if len(response) == 0: return "No good Google Search Result was found" for result in response: if "snippet" in result: snippets.append(result["snippet"]) return " ".join(snippets) def get_tool_call_format(self): tool_call_format = { "type": "function", "function": { "name": "google_search", "description": "search information using google search api", "parameters": { "type": "object", "properties": { "query": { "type": "string", "description": "prompt description of the image to be generated" } }, "required": [ "query" ] } } } return tool_call_format ================================================ FILE: pyopenagi/tools/imdb/top_movie.py ================================================ from ..base import BaseRapidAPITool from typing import Any, Dict, List, Optional # from pydantic import root_validator from pyopenagi.utils.utils import get_from_env import requests class TopMovieAPI(BaseRapidAPITool): def __init__(self): super().__init__() self.url = "https://imdb-top-100-movies.p.rapidapi.com/" self.host_name = "imdb-top-100-movies.p.rapidapi.com" self.api_key = get_from_env("RAPID_API_KEY") def run(self, params): start = int(params["start"]) if "start" in params else 1 end = int(params["end"]) headers = { "X-RapidAPI-Key": self.api_key, "X-RapidAPI-Host": self.host_name } response = requests.get(self.url, headers=headers).json() result = self.parse_result(response, start, end) return result def parse_result(self, response, start, end) -> str: result = [] # print(response) for i in range(start, end): item = response[i] result.append(f'{item["title"]}, {item["genre"]}, {item["rating"]}, published in {item["year"]}') return f"Top {start}-{end} series ranked by IMDB are: " + ";".join(result) def get_tool_call_format(self): tool_call_format = { "type": "function", "function": { "name": "top_movies", "description": "Query the latest top start-to-end movies ranked by Imdb", "parameters": { "type": "object", "properties": { "start": { "type": "string", "description": "start of the rank range of the Imdb movies", "default": "1" }, "end": { "type": "string", "description": "end of the rank range of the Imdb movies" } }, "required": [ "end" ] } } } return tool_call_format ================================================ FILE: pyopenagi/tools/imdb/top_movies.py ================================================ from ..base import BaseRapidAPITool # from pydantic import root_validator from pyopenagi.utils.utils import get_from_env import requests class TopMovies(BaseRapidAPITool): def __init__(self): super().__init__() self.url = "https://imdb-top-100-movies.p.rapidapi.com/" self.host_name = "imdb-top-100-movies.p.rapidapi.com" self.api_key = get_from_env("RAPID_API_KEY") def run(self, params): start = int(params["start"]) if "start" in params else 1 end = int(params["end"]) headers = { "X-RapidAPI-Key": self.api_key, "X-RapidAPI-Host": self.host_name } response = requests.get(self.url, headers=headers).json() result = self.parse_result(response, start, end) return result def parse_result(self, response, start, end) -> str: result = [] # print(response) for i in range(start, end): item = response[i] result.append(f'{item["title"]}, {item["genre"]}, {item["rating"]}, published in {item["year"]}') return f"Top {start}-{end} series ranked by IMDB are: " + ";".join(result) def get_tool_call_format(self): tool_call_format = { "type": "function", "function": { "name": "top_movies", "description": "Query the latest top start-to-end movies ranked by Imdb", "parameters": { "type": "object", "properties": { "start": { "type": "string", "description": "start of the rank range of the Imdb movies", "default": "1" }, "end": { "type": "string", "description": "end of the rank range of the Imdb movies" } }, "required": [ "end" ] } } } return tool_call_format ================================================ FILE: pyopenagi/tools/imdb/top_series.py ================================================ from ..base import BaseRapidAPITool from pyopenagi.utils.utils import get_from_env import requests class TopSeries(BaseRapidAPITool): def __init__(self): super().__init__() self.url = "https://imdb-top-100-movies.p.rapidapi.com/series/" self.host_name = "imdb-top-100-movies.p.rapidapi.com" self.api_key = get_from_env("RAPID_API_KEY") def run(self, params): start = int(params["start"]) if "start" in params else 1 end = int(params["end"]) headers = { "X-RapidAPI-Key": self.api_key, "X-RapidAPI-Host": self.host_name } response = requests.get(self.url, headers=headers).json() result = self.parse_result(response, start, end) return result def parse_result(self, response, start, end) -> str: result = [] for i in range(start, end): item = response[i] result.append(f'{item["title"]}, {item["genre"]}, {item["rating"]}, published in {item["year"]}') return f"Top {start}-{end} series ranked by IMDB are: " + ";".join(result) def get_tool_call_format(self): tool_call_format = { "type": "function", "function": { "name": "imdb_top_series", "description": "Query the latest top start-to-end series ranked by Imdb", "parameters": { "type": "object", "properties": { "start": { "type": "string", "description": "start of the rank range of the Imdb series", "default": "1" }, "end": { "type": "string", "description": "end of the rank range of the Imdb series" } }, "required": [ "end" ] } } } return tool_call_format ================================================ FILE: pyopenagi/tools/impira/doc_question_answering.py ================================================ import requests from ...utils.utils import get_from_env from ..base import BaseHuggingfaceTool import base64 class DocQuestionAnswering(BaseHuggingfaceTool): def __init__(self): super().__init__() def run(self, params): API_URL = "https://api-inference.huggingface.co/models/impira/layoutlm-document-qa" headers = {"Authorization": "Bearer " + get_from_env("HF_AUTH_TOKENS")} question = params["question"] path = params["path"] with open(path, "rb") as f: img = f.read() payload = { "input": { "image": base64.b64encode(img).decode("utf-8") }, "question": question } response = requests.post(API_URL, headers=headers, json=payload) return response.json() def get_tool_call_format(self): tool_call_format = { "type": "function", "function": { "name": "doc_question_answering", "description": "answer the question based on the given document", "parameters": { "type": "object", "properties": { "question": { "type": "string", "description": "question that needs to be answered" }, "path": { "type": "string", "description": "path of the document" } }, "required": [ "question", "path" ] } } } return tool_call_format ================================================ FILE: pyopenagi/tools/meteosource_weather/find_place.py ================================================ from ..base import BaseRapidAPITool # from pydantic import root_validator from pyopenagi.utils.utils import get_from_env import requests class SongAutocompleteAPI(BaseRapidAPITool): def __init__(self): super().__init__() self.url = "https://ai-weather-by-meteosource.p.rapidapi.com/find_places" self.host_name = "ai-weather-by-meteosource.p.rapidapi.com" self.api_key = get_from_env("RAPID_API_KEY") def run(self, params): headers = { "X-RapidAPI-Key": self.api_key, "X-RapidAPI-Host": self.host_name } try: self.query_string = { "text": params["text"], "language": params["language"] } except ValueError: raise KeyError( "The keys in params do not match the excepted keys in params for weather find place api. " "Please make sure it contains two keys: 'text' and 'language'" ) response = requests.get(self.url, headers=headers, params=self.query_string).json() result = self.parse_result(response) return result def parse_result(self, response) -> str: location = [ response["radm_area1"], response["adm_area2"], response["country"], response["lat"], response["lon"] ] return f"Found place of {response["name"]}: " + ",".join(location) ================================================ FILE: pyopenagi/tools/moonphase/moon_phase_search.py ================================================ from ..base import BaseRapidAPITool from pyopenagi.utils.utils import get_from_env import requests class MoonPhaseSearch(BaseRapidAPITool): def __init__(self): super().__init__() self.url = "https://moon-phase.p.rapidapi.com/basic" self.host_name = "moon-phase.p.rapidapi.com" self.api_key = get_from_env("RAPID_API_KEY") def run(self): headers = { "X-RapidAPI-Key": self.api_key, "X-RapidAPI-Host": self.host_name } response = requests.get(self.url, headers=headers) result = self.parse_result(response) return result def parse_result(self, response) -> str: 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.' ================================================ FILE: pyopenagi/tools/openai/speech_to_text.py ================================================ import requests import soundfile as sf from ...utils.utils import get_from_env from ..base import BaseHuggingfaceTool class SpeechToText(BaseHuggingfaceTool): def __init__(self): super().__init__() def run(self, params): API_URL = "https://api-inference.huggingface.co/models/openai/whisper-large-v3" headers = {"Authorization": "Bearer " + get_from_env("HF_AUTH_TOKENS")} path = params["path"] data = sf.read(path) response = requests.post(API_URL, headers=headers, data=data) text = response.content return text def get_tool_call_format(self): tool_call_format = { "type": "function", "function": { "name": "speech_to_text", "description": "translate the voice into texts", "parameters": { "type": "object", "properties": { "path": { "type": "string", "description": "path of the saved audio" } }, "required": [ "path" ] } } } return tool_call_format ================================================ FILE: pyopenagi/tools/shazam/song_auto_complete.py ================================================ from ..base import BaseRapidAPITool # from pydantic import root_validator from pyopenagi.utils.utils import get_from_env import requests class SongAutoComplete(BaseRapidAPITool): def __init__(self): super().__init__() self.url = "https://shazam.p.rapidapi.com/auto-complete" self.host_name = "shazam.p.rapidapi.com" self.api_key = get_from_env("RAPID_API_KEY") def run(self, params): headers = { "X-RapidAPI-Key": self.api_key, "X-RapidAPI-Host": self.host_name } try: self.query_string = { "term": params["term"], "locale": params["locale"] } except ValueError: raise KeyError( "The keys in params do not match the excepted keys in params for currency converter api. " "Please make sure it contains two keys: 'term' and 'locale'" ) response = requests.get(self.url, headers=headers, params=self.query_string).json() result = self.parse_result(response) return result def parse_result(self, response) -> str: return "Completion hints are: " + ",".join(response["hints"].values()) ================================================ FILE: pyopenagi/tools/stability-ai/sdxl_turbo.py ================================================ from diffusers import AutoPipelineForText2Image import torch from ..base import BaseHuggingfaceTool class SdxlTurbo(BaseHuggingfaceTool): def __init__(self): super().__init__() self.pipe = AutoPipelineForText2Image.from_pretrained("stabilityai/sdxl-turbo", torch_dtype=torch.float16, variant="fp16") def run(self, params): prompt = params["prompt"] self.pipe.to("cuda") image = self.pipe(prompt=prompt, num_inference_steps=1, guidance_scale=0.0).images[0] return image def get_tool_call_format(self): tool_call_format = { "type": "function", "function": { "name": "sdxl_turbo", "description": "generate images with the given texts", "parameters": { "type": "object", "properties": { "prompt": { "type": "string", "description": "prompt description of the image to be generated" } }, "required": [ "prompt" ] } } } return tool_call_format ================================================ FILE: pyopenagi/tools/stability-ai/text_to_image.py ================================================ from ...utils.utils import get_from_env from ..base import BaseHuggingfaceTool import requests class TextToImage(BaseHuggingfaceTool): def __init__(self): super().__init__() def run(self, params): API_URL = "https://api-inference.huggingface.co/models/stabilityai/stable-diffusion-xl-base-1.0" headers = {"Authorization": "Bearer " + get_from_env("HF_AUTH_TOKENS")} prompt = params["prompt"] path = params["path"] payload = { "inputs": prompt } response = requests.post(API_URL, headers=headers, json=payload) image_bytes = response.content # You can access the image with PIL.Image for example import io from PIL import Image image = Image.open(io.BytesIO(image_bytes)) image.save(path) return f"a generated image saved at {path}" def get_tool_call_format(self): tool_call_format = { "type": "function", "function": { "name": "text_to_image", "description": "generate images with the given texts", "parameters": { "type": "object", "properties": { "prompt": { "type": "string", "description": "prompt description of the image to be generated" }, "path": { "type": "string", "description": "path to save the generated image" } }, "required": [ "prompt", "path" ] } } } return tool_call_format ================================================ FILE: pyopenagi/tools/suno/text_to_speech.py ================================================ import requests from ...utils.utils import get_from_env from ..base import BaseHuggingfaceTool class TextToSpeech(BaseHuggingfaceTool): def __init__(self): super().__init__() def run(self, params): API_URL = "https://api-inference.huggingface.co/models/suno/bark" headers = {"Authorization": "Bearer " + get_from_env("HF_AUTH_TOKENS")} prompt = params["prompt"] path = params["path"] payload = { "prompt": prompt } response = requests.post(API_URL, headers=headers, json=payload) with open(path,"wb") as f: f.write(response.content) return f"a generated audio saved at {path}" # pass def get_tool_call_format(self): tool_call_format = { "type": "function", "function": { "name": "text_to_speech", "description": "generate voice based on the text", "parameters": { "type": "object", "properties": { "prompt": { "type": "string", "description": "text description" }, "path": { "type": "string", "description": "path to save the audio" } }, "required": [ "prompt", "path" ] } } } return tool_call_format ================================================ FILE: pyopenagi/tools/timbrooks/image_to_image.py ================================================ from PIL import Image import torch from diffusers import StableDiffusionInstructPix2PixPipeline, EulerAncestralDiscreteScheduler from ..base import BaseHuggingfaceTool class ImageToImage(BaseHuggingfaceTool): def __init__(self): super().__init__() self.model_id = "timbrooks/instruct-pix2pix" self.pipe = StableDiffusionInstructPix2PixPipeline.from_pretrained(self.model_id, torch_dtype=torch.float16, safety_checker=None) self.pipe.to("cuda") self.pipe.scheduler = EulerAncestralDiscreteScheduler.from_config(self.pipe.scheduler.config) def run(self, params): path = params["old_path"] image = Image.open(path) prompt = params["prompt"] new_image = self.pipe(prompt, image=image, num_inference_steps=10, image_guidance_scale=1).images new_path = params["new_path"] new_image.save(path) return f"a new image saved at {new_path}" def get_tool_call_format(self): tool_call_format = { "type": "function", "function": { "name": "text_to_image", "description": "generate images with the given texts", "parameters": { "type": "object", "properties": { "prompt": { "type": "string", "description": "prompt description of the image to be generated" }, "old_path": { "type": "string", "description": "path to load the old image" }, "new_path": { "type": "string", "description": "path to save the new generated image" } }, "required": [ "prompt", "old_path", "new_path" ] } } } return tool_call_format ================================================ FILE: pyopenagi/tools/transcriber/transcriber.py ================================================ from ..base import BaseTool from time import sleep class Transcriber(BaseTool): def __init__(self): """ big library, not everyone needs it installed """ try: from RealtimeSTT import AudioToTextRecorder except ImportError: raise ImportError( "Please install RealtimeSTT: `pip install RealtimeSTT`" ) # this is hardcoded for now self.recorder = AudioToTextRecorder( model="tiny.en", ) def run(self, params: dict): duration = 5 try: duration = int(params["duration"]) except ValueError: raise KeyError( "The keys in params do not match the excepted key in params for transcriber api. " "Please make sure it contain the key 'duration'" ) self.record.start() sleep(duration) self.recorder.stop() return self.recorder.text() def get_tool_call_format(self): tool_call_format = { "type": "function", "function": { "name": "transcriber", "description": "Transcribes audiio into text", "parameters": { "type": "object", "properties": { "duration": { "type": "string", "description": "How long to record audio for in seconds", }, }, "required": [] } } } return tool_call_format ================================================ FILE: pyopenagi/tools/travel_planner/accommodations.py ================================================ import pandas as pd import os from pandas import DataFrame from ..base import BaseTool class Accommodations(BaseTool): def __init__(self, path="../../environments/travelPlanner/accommodations/clean_accommodations_2022.csv"): current_dir = os.path.dirname(os.path.abspath(__file__)) self.path = os.path.join(current_dir, path) self.data = pd.read_csv(self.path).dropna()[ ['NAME', 'price', 'room type', 'house_rules', 'minimum nights', 'maximum occupancy', 'review rate number', 'city']] print("Accommodations loaded.") def load_db(self): self.data = pd.read_csv(self.path).dropna() def run(self, city: str, ) -> DataFrame: """Search for accommodations by city.""" results = self.data[self.data["city"] == city] if len(results) == 0: return "There is no attraction in this city." return results def get_tool_call_format(self): tool_call_format = { "type": "function", "function": { "name": "Accommodations", "description": "Search for an Accommodations by query", } } return tool_call_format ================================================ FILE: pyopenagi/tools/travel_planner/attractions.py ================================================ import pandas as pd import os from pandas import DataFrame from ..base import BaseTool class Attractions(BaseTool): def __init__(self, path="../../environments/travelPlanner/attractions/attractions.csv"): current_dir = os.path.dirname(os.path.abspath(__file__)) self.path = os.path.join(current_dir, path) self.data = pd.read_csv(self.path).dropna()[ ['Name', 'Latitude', 'Longitude', 'Address', 'Phone', 'Website', "City"]] print("Attractions loaded.") def load_db(self): self.data = pd.read_csv(self.path) def run(self, city: str, ) -> DataFrame: """Search for Accommodations by city and date.""" results = self.data[self.data["City"] == city] # the results should show the index results = results.reset_index(drop=True) if len(results) == 0: return "There is no attraction in this city." return results def get_tool_call_format(self): tool_call_format = { "type": "function", "function": { "name": "Attractions", "description": "Search for Attractions by query", } } return tool_call_format ================================================ FILE: pyopenagi/tools/travel_planner/cities.py ================================================ import os from ..base import BaseTool class Cities(BaseTool): def __init__(self, path="../../environments/travelPlanner/background/citySet_with_states.txt") -> None: current_dir = os.path.dirname(os.path.abspath(__file__)) self.path = os.path.join(current_dir, path) self.load_data() print("Cities loaded.") def load_data(self): cityStateMapping = open(self.path, "r").read().strip().split("\n") self.data = {} for unit in cityStateMapping: city, state = unit.split("\t") if state not in self.data: self.data[state] = [city] else: self.data[state].append(city) def run(self, state) -> dict: if state not in self.data: return ValueError("Invalid State") else: return self.data[state] def get_tool_call_format(self): tool_call_format = { "type": "function", "function": { "name": "Cities", "description": "Search for Cities by query", } } return tool_call_format ================================================ FILE: pyopenagi/tools/travel_planner/flights.py ================================================ import pandas as pd import os from pandas import DataFrame from ..base import BaseTool class Flights(BaseTool): def __init__(self, path="../../environments/travelPlanner/flights/clean_Flights_2022.csv"): current_dir = os.path.dirname(os.path.abspath(__file__)) self.path = os.path.join(current_dir, path) self.data = pd.read_csv(self.path).dropna()[ ['Flight Number', 'Price', 'DepTime', 'ArrTime', 'ActualElapsedTime', 'FlightDate', 'OriginCityName', 'DestCityName', 'Distance']] print("Flights loaded.") def load_db(self): self.data = pd.read_csv(self.path).dropna().rename(columns={'Unnamed: 0': 'Flight Number'}) def run(self, origin: str, destination: str, departure_date: str, ) -> DataFrame: """Search for flights by origin, destination, and departure date.""" results = self.data[self.data["OriginCityName"] == origin] results = results[results["DestCityName"] == destination] results = results[results["FlightDate"] == departure_date] if len(results) == 0: return "There is no flight from {} to {} on {}.".format(origin, destination, departure_date) return results def get_tool_call_format(self): tool_call_format = { "type": "function", "function": { "name": "Flights", "description": "Search for Flights by query", } } return tool_call_format ================================================ FILE: pyopenagi/tools/travel_planner/google_distance_matrix.py ================================================ import re import os import pandas as pd import numpy as np from ..base import BaseTool # This tool refers to the "DistanceMatrix" in the paper. Considering this data obtained from Google API, # we consistently use this name in the code. Please be assured that this will not influence the experiment results # shown in the paper. class GoogleDistanceMatrix(BaseTool): def __init__(self, path="../../environments/travelPlanner/googleDistanceMatrix/distance.csv", subscription_key: str = "") -> None: self.gplaces_api_key: str = subscription_key current_dir = os.path.dirname(os.path.abspath(__file__)) self.path = os.path.join(current_dir, path) self.data = pd.read_csv(self.path) print("GoogleDistanceMatrix loaded.") def run(self, origin, destination, mode='driving'): origin = extract_before_parenthesis(origin) destination = extract_before_parenthesis(destination) info = {"origin": origin, "destination": destination, "cost": None, "duration": None, "distance": None} response = self.data[(self.data['origin'] == origin) & (self.data['destination'] == destination)] if len(response) > 0: if response['duration'].values[0] is None or response['distance'].values[0] is None or \ response['duration'].values[0] is np.nan or response['distance'].values[0] is np.nan: return "No valid information." info["duration"] = response['duration'].values[0] info["distance"] = response['distance'].values[0] if 'driving' in mode: info["cost"] = int(eval(info["distance"].replace("km", "").replace(",", "")) * 0.05) elif mode == "taxi": info["cost"] = int(eval(info["distance"].replace("km", "").replace(",", ""))) if 'day' in info["duration"]: return "No valid information." return f"{mode}, from {origin} to {destination}, duration: {info['duration']}, distance: {info['distance']}, cost: {info['cost']}" return f"{mode}, from {origin} to {destination}, no valid information." def get_tool_call_format(self): tool_call_format = { "type": "function", "function": { "name": "GoogleDistanceMatrix", "description": "Distance information", } } return tool_call_format def extract_before_parenthesis(s): match = re.search(r'^(.*?)\([^)]*\)', s) return match.group(1) if match else s ================================================ FILE: pyopenagi/tools/travel_planner/notebook.py ================================================ from pandas import DataFrame from ..base import BaseTool class Notebook(BaseTool): def __init__(self) -> None: self.data = [] def run(self, input_data: DataFrame, short_description: str): self.data.append({"Short Description": short_description, "Content": input_data}) return f"The information has been recorded in Notebook, and its index is {len(self.data) - 1}." def update(self, input_data: DataFrame, index: int, short_decription: str): self.data[index]["Content"] = input_data self.data[index]["Short Description"] = short_decription return "The information has been updated in Notebook." def list(self): results = [] for idx, unit in enumerate(self.data): results.append({"index": idx, "Short Description": unit['Short Description']}) return results def list_all(self): results = [] for idx, unit in enumerate(self.data): if type(unit['Content']) is DataFrame: results.append({"index": idx, "Short Description": unit['Short Description'], "Content": unit['Content'].to_string(index=False)}) else: results.append( {"index": idx, "Short Description": unit['Short Description'], "Content": unit['Content']}) return results def read(self, index): return self.data[index] def reset(self): self.data = [] def get_tool_call_format(self): tool_call_format = { "type": "function", "function": { "name": "Notebook", "description": "Note information", } } return tool_call_format ================================================ FILE: pyopenagi/tools/travel_planner/planner.py ================================================ 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). ***** Example ***** Query: 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? Travel Plan: Day 1: Current City: from Ithaca to Charlotte Transportation: Flight Number: F3633413, from Ithaca to Charlotte, Departure Time: 05:38, Arrival Time: 07:46 Breakfast: Nagaland's Kitchen, Charlotte Attraction: The Charlotte Museum of History, Charlotte Lunch: Cafe Maple Street, Charlotte Dinner: Bombay Vada Pav, Charlotte Accommodation: Affordable Spacious Refurbished Room in Bushwick!, Charlotte Day 2: Current City: Charlotte Transportation: - Breakfast: Olive Tree Cafe, Charlotte Attraction: The Mint Museum, Charlotte;Romare Bearden Park, Charlotte. Lunch: Birbal Ji Dhaba, Charlotte Dinner: Pind Balluchi, Charlotte Accommodation: Affordable Spacious Refurbished Room in Bushwick!, Charlotte Day 3: Current City: from Charlotte to Ithaca Transportation: Flight Number: F3786167, from Charlotte to Ithaca, Departure Time: 21:42, Arrival Time: 23:26 Breakfast: Subway, Charlotte Attraction: Books Monument, Charlotte. Lunch: Olive Tree Cafe, Charlotte Dinner: Kylin Skybar, Charlotte Accommodation: - ***** Example Ends ***** Given information: {text} Query: {query} Travel Plan:""" ================================================ FILE: pyopenagi/tools/travel_planner/restaurants.py ================================================ import pandas as pd import os from pandas import DataFrame from ..base import BaseTool class Restaurants(BaseTool): def __init__(self, path="../../environments/travelPlanner/restaurants/clean_restaurant_2022.csv"): super().__init__() current_dir = os.path.dirname(os.path.abspath(__file__)) self.path = os.path.join(current_dir, path) self.data = pd.read_csv(self.path).dropna()[['Name', 'Average Cost', 'Cuisines', 'Aggregate Rating', 'City']] print("Restaurants loaded.") def load_db(self): self.data = pd.read_csv(self.path).dropna() def run(self, city: str, ) -> DataFrame: """Search for restaurant .""" results = self.data[self.data["City"] == city] if len(results) == 0: return "There is no restaurant in this city." return results def get_tool_call_format(self): tool_call_format = { "type": "function", "function": { "name": "Restaurants", "description": "Search for Restaurants by query", } } return tool_call_format ================================================ FILE: pyopenagi/tools/trip_advisor/airport_search.py ================================================ from ..base import BaseRapidAPITool from pyopenagi.utils.utils import get_from_env import requests import json class AirportSearch(BaseRapidAPITool): def __init__(self): super().__init__() self.url = "https://tripadvisor16.p.rapidapi.com/api/v1/flights/searchAirport" self.host_name = "tripadvisor16.p.rapidapi.com" self.api_key = get_from_env("RAPID_API_KEY") def run(self, params: dict): headers = { "X-RapidAPI-Key": self.api_key, "X-RapidAPI-Host": self.host_name } try: self.query_string = { "query": params["query"], } except ValueError: raise KeyError( "The keys in params do not match the excepted keys in params for tripadvisor search airport api. " "Please make sure it contains the key: 'query'" ) # print(self.query_string) response = requests.get(self.url, headers=headers, params=self.query_string).json() return self.parse_result(response) def parse_result(self, response) -> str: limited_results = response['data'][:2] simplified_results = [] for result in limited_results: simplified_result = { 'name': result['name'], 'airportCode': result['airportCode'], 'coords': result['coords'] } simplified_results.append(simplified_result) return json.dumps(simplified_results) def get_tool_call_format(self): tool_call_format = { "type": "function", "function": { "name": "airport_search", "description": "Search for an airport by query", "parameters": { "type": "object", "properties": { "query": { "type": "string", "description": "Search query for airport" } }, "required": [ "query" ] } } } return tool_call_format ================================================ FILE: pyopenagi/tools/trip_advisor/flight_search.py ================================================ from ..base import BaseRapidAPITool from pyopenagi.utils.utils import get_from_env import requests import json class FlightSearch(BaseRapidAPITool): def __init__(self): super().__init__() self.url = "https://tripadvisor16.p.rapidapi.com/api/v1/flights/searchFlights" self.host_name = "tripadvisor16.p.rapidapi.com" self.api_key = get_from_env("RAPID_API_KEY") def run(self, params: dict): headers = { "X-RapidAPI-Key": self.api_key, "X-RapidAPI-Host": self.host_name } try: self.query_string = { "sourceAirportCode": params["sourceAirportCode"], "date": params["date"], "destinationAirportCode": params["destinationAirportCode"], "itineraryType": params["itineraryType"], "sortOrder": params["sortOrder"], "classOfService": params["classOfService"], "returnDate": params["returnDate"] } except ValueError: raise KeyError( "The keys in params do not match the excepted keys in params for tripadvisor search flight api. " "Please make sure it contains following required keys: " "sourceAirportCode", "destinationAirportCode", "itineraryType", "sortOrder", "classOfService", "returnDate", "date" ) response = requests.get(self.url, headers=headers, params=self.query_string).json() return self.parse_result(response) def parse_result(self, response) -> str: # Accessing the 'flights' data from within the 'data' key if 'data' in response and 'flights' in response['data']: flights_data = response['data']['flights'] simplified_results = [] flight_count = 0 for flight in flights_data: if flight_count >= 2: break for segment in flight['segments']: for leg in segment['legs']: simplified_result = { 'originStationCode': leg['originStationCode'], 'destinationStationCode': leg['destinationStationCode'], 'departureDateTime': leg['departureDateTime'], 'arrivalDateTime': leg['arrivalDateTime'], 'classOfService': leg['classOfService'], 'marketingCarrierCode': leg['marketingCarrierCode'], 'operatingCarrierCode': leg['operatingCarrierCode'], 'flightNumber': leg['flightNumber'], 'numStops': leg['numStops'], 'distanceInKM': leg['distanceInKM'], 'isInternational': leg['isInternational'] } simplified_results.append(simplified_result) flight_count += 1 return json.dumps(simplified_results) else: return json.dumps([]) def get_tool_call_format(self): tool_call_format = { "type": "function", "function": { "name": "flight_search", "description": "Provides details about a flight", "parameters": { "type": "object", "properties": { "sourceAirportCode": { "type": "string", "description": "The source airport code of the flight to search for" }, "date": { "type": "string", "format": "date", "description": "The date of the flight" }, "returnDate": { "type": "string", "format": "date", "description": "The return date of the flight" }, "destinationAirportCode": { "type": "string", "description": "The destination airport code of the flight" }, "itineraryType": { "type": "string", "enum": [ "ONE_WAY", "ROUND_TRIP" ], "description": "The type of itinerary" }, "sortOrder": { "type": "string", "enum": [ "ML_BEST_VALUE", "DURATION", "PRICE", "EARLIEST_OUTBOUND_DEPARTURE", "EARLIEST_OUTBOUND_ARRIVAL", "LATEST_OUTBOUND_DEPARTURE", "LATEST_OUTBOUND_ARRIVAL" ], "description": "The order to sort the results" }, "classOfService": { "type": "string", "enum": [ "ECONOMY", "PREMIUM_ECONOMY", "BUSINESS", "FIRST" ], "description": "The class of service for the flight" }, "numSeniors": { "type": "number", "description": "The number of seniors in the itinerary" }, "numAdults": { "type": "number", "description": "The number of adults in the itinerary" } }, "required": [ "sourceAirportCode", "date", "destinationAirportCode", "itineraryType", "sortOrder", "classOfService", "numSeniors", "numAdults", "returnDate" ] } } } return tool_call_format ================================================ FILE: pyopenagi/tools/trip_advisor/get_hotel_details.py ================================================ from ..base import BaseRapidAPITool from pyopenagi.utils.utils import get_from_env import requests import json class GetHotelDetails(BaseRapidAPITool): def __init__(self): super().__init__() self.url = "https://tripadvisor16.p.rapidapi.com/api/v1/hotels/getHotelDetails" self.host_name = "tripadvisor16.p.rapidapi.com" self.api_key = get_from_env("RAPID_API_KEY") def run(self, params: dict): headers = { "X-RapidAPI-Key": self.api_key, "X-RapidAPI-Host": self.host_name } try: self.query_string = { "id": params["id"], "checkIn": params["checkIn"], "checkOut": params["checkOut"], } except ValueError: raise KeyError( "The keys in params do not match the excepted keys in params for tripadvisor get hotel details api. " "Please make sure it contains following required keys: " "id", "checkIn", "checkOut", ) response = requests.get(self.url, headers=headers, params=self.query_string).json() return self.parse_result(response) def parse_result(self, response) -> str: if 'data' in response: hotel_data = response['data'] relevant_info = { 'name': hotel_data.get('title', ''), 'rating': hotel_data.get('rating', ''), 'address': hotel_data.get('location', {}).get('address', ''), 'amenities': [amenity['title'] for amenity in hotel_data.get('about', {}).get('content', []) if amenity['title'] == 'Amenities'], 'description': hotel_data.get('about', {}).get('content', [{}])[0].get('content', ''), 'restaurantsNearby': [{ 'title': hotel_data.get('restaurantsNearby', {}).get('content', [{}])[0].get('title', ''), 'rating': hotel_data.get('restaurantsNearby', {}).get('content', [{}])[0].get('bubbleRating', {}).get('rating', ''), 'primaryInfo': hotel_data.get('restaurantsNearby', {}).get('content', [{}])[0].get('primaryInfo', ''), 'distance': hotel_data.get('restaurantsNearby', {}).get('content', [{}])[0].get('distance', ''), }], 'attractionsNearby': [{ 'title': hotel_data.get('attractionsNearby', {}).get('content', [{}])[0].get('title', ''), 'rating': hotel_data.get('attractionsNearby', {}).get('content', [{}])[0].get('bubbleRating', {}).get('rating', ''), 'primaryInfo': hotel_data.get('attractionsNearby', {}).get('content', [{}])[0].get('primaryInfo', ''), 'distance': hotel_data.get('attractionsNearby', {}).get('content', [{}])[0].get('distance', ''), }] } return json.dumps(relevant_info) else: return json.dumps({}) def get_tool_call_format(self): tool_call_format = { "type": "function", "function": { "name": "get_hotel_details", "description": "Provides details about a hotel", "parameters": { "type": "object", "properties": { "id": { "type": "string", "description": "The ID of the hotel to get details for" }, "checkIn": { "type": "string", "format": "date", "description": "The check in date" }, "checkOut": { "type": "string", "format": "date", "description": "The check out date" } }, "required": [ "id", "checkIn", "checkOut" ] } } } return tool_call_format ================================================ FILE: pyopenagi/tools/trip_advisor/get_restaurant_details.py ================================================ from ..base import BaseRapidAPITool from pyopenagi.utils.utils import get_from_env import requests import json class GetRestaurantDetails(BaseRapidAPITool): def __init__(self): super().__init__() self.url = "https://tripadvisor16.p.rapidapi.com/api/v1/restaurant/getRestaurantDetails" self.host_name = "tripadvisor16.p.rapidapi.com" self.api_key = get_from_env("RAPID_API_KEY") def run(self, params: dict): headers = { "X-RapidAPI-Key": self.api_key, "X-RapidAPI-Host": self.host_name } try: self.query_string = { "restaurantsId": params["restaurantsId"], } except ValueError: raise KeyError( "The keys in params do not match the excepted keys in params for tripadvisor get restaurant details api. " "Please make sure it contains the key: 'restaurantsID'" ) response = requests.get(self.url, headers=headers, params=self.query_string).json() return self.parse_result(response) def parse_result(self, response) -> str: location = response["data"]["location"] useful_info = { "name": location.get("name"), "latitude": location.get("latitude"), "longitude": location.get("longitude"), "num_reviews": location.get("num_reviews"), "rating": location.get("rating"), "price_level": location.get("price_level"), "address": location.get("address"), "phone": location.get("phone"), "website": location.get("website"), "cuisine": [cuisine["name"] for cuisine in location.get("cuisine", [])], "hours": location.get("hours", {}).get("week_ranges", []) } return json.dumps(useful_info) def get_tool_call_format(self): tool_call_format = { "type": "function", "function": { "name": "get_restaurant_details", "description": "Provides details about a restaurant", "parameters": { "type": "object", "properties": { "restaurantsId": { "type": "string", "description": "The ID of the restaurant to get details for" } }, "required": [ "restaurantsId" ] } } } return tool_call_format ================================================ FILE: pyopenagi/tools/trip_advisor/hotel_location_search.py ================================================ from ..base import BaseRapidAPITool from pyopenagi.utils.utils import get_from_env import requests import json class HotelLocationSearch(BaseRapidAPITool): def __init__(self): super().__init__() self.url = "https://tripadvisor16.p.rapidapi.com/api/v1/hotels/searchLocation" self.host_name = "tripadvisor16.p.rapidapi.com" self.api_key = get_from_env("RAPID_API_KEY") def run(self, params: dict): headers = { "X-RapidAPI-Key": self.api_key, "X-RapidAPI-Host": self.host_name } try: self.query_string = { "query": params["query"], } except ValueError: raise KeyError( "The keys in params do not match the excepted keys in params for tripadvisor search hotel location api. " "Please make sure it contains the key: 'query'" ) # print(self.query_string) response = requests.get(self.url, headers=headers, params=self.query_string).json() return json.dumps(response) def parse_result(self, response) -> str: raise NotImplementedError def get_tool_call_format(self): tool_call_format = { "type": "function", "function": { "name": "hotel_location_search", "description": "Search for a hotel location by query", "parameters": { "type": "object", "properties": { "query": { "type": "string", "description": "Search query for hotel location" } }, "required": [ "query" ] } } } return tool_call_format ================================================ FILE: pyopenagi/tools/trip_advisor/hotel_search.py ================================================ from ..base import BaseRapidAPITool from pyopenagi.utils.utils import get_from_env import requests import json class HotelSearch(BaseRapidAPITool): def __init__(self): super().__init__() self.url = "https://tripadvisor16.p.rapidapi.com/api/v1/hotels/searchHotels" self.host_name = "tripadvisor16.p.rapidapi.com" self.api_key = get_from_env("RAPID_API_KEY") def run(self, params: dict): headers = { "X-RapidAPI-Key": self.api_key, "X-RapidAPI-Host": self.host_name } try: self.query_string = { "geoId": params["geoId"], "checkIn": params["checkIn"], "checkOut": params["checkOut"], } except ValueError: raise KeyError( "The keys in params do not match the excepted keys in params for tripadvisor search hotel api. " "Please make sure it contains following required keys: " "geoId", "checkIn", "checkOut", ) response = requests.get(self.url, headers=headers, params=self.query_string).json() return self.parse_result(response) def parse_result(self, response) -> str: if 'data' in response and 'data' in response['data']: hotels_data = response['data']['data'][:2] relevant_info = [] for hotel in hotels_data: relevant_info.append({ 'id': hotel['id'], 'title': hotel['title'], 'secondaryInfo': hotel['secondaryInfo'], 'bubbleRating': hotel['bubbleRating'], 'priceForDisplay': hotel['priceForDisplay'], 'priceDetails': hotel['priceDetails'], 'priceSummary': hotel['priceSummary'] }) return json.dumps(relevant_info) else: return json.dumps([]) def get_tool_call_format(self): tool_call_format = { "type": "function", "function": { "name": "hotel_search", "description": "Provides details about a hotel", "parameters": { "type": "object", "properties": { "geoId": { "type": "string", "description": "The geoId of the hotel to search for" }, "checkIn": { "type": "string", "format": "date", "description": "The check in date" }, "checkOut": { "type": "string", "format": "date", "description": "The check out date" } }, "required": [ "geoId", "checkIn", "checkOut" ] } } } return tool_call_format ================================================ FILE: pyopenagi/tools/trip_advisor/restaurant_location_search.py ================================================ from ..base import BaseRapidAPITool from pyopenagi.utils.utils import get_from_env import requests import json class RestaurantLocationSearch(BaseRapidAPITool): def __init__(self): super().__init__() self.url = "https://tripadvisor16.p.rapidapi.com/api/v1/restaurant/searchLocation" self.host_name = "tripadvisor16.p.rapidapi.com" self.api_key = get_from_env("RAPID_API_KEY") def run(self, params: dict): headers = { "X-RapidAPI-Key": self.api_key, "X-RapidAPI-Host": self.host_name } try: self.query_string = { "query": params["query"], } except ValueError: raise KeyError( "The keys in params do not match the excepted keys in params for tripadvisor search restaurant location api. " "Please make sure it contains the key: 'query'" ) # print(self.query_string) response = requests.get(self.url, headers=headers, params=self.query_string).json() return self.parse_result(response) def parse_result(self, response) -> str: limited_results = response['data'][:2] simplified_results = [] for result in limited_results: simplified_result = { 'locationId': result['locationId'], 'localizedName': result['localizedName'], 'latitude': result['latitude'], 'longitude': result['longitude'] } simplified_results.append(simplified_result) return json.dumps(simplified_results) def get_tool_call_format(self): tool_call_format = { "type": "function", "function": { "name": "restaurant_location_search", "description": "Search for a restaurant location by query", "parameters": { "type": "object", "properties": { "query": { "type": "string", "description": "Search query for restaurant location" } }, "required": [ "query" ] } } } return tool_call_format ================================================ FILE: pyopenagi/tools/trip_advisor/restaurant_search.py ================================================ from ..base import BaseRapidAPITool from pyopenagi.utils.utils import get_from_env import requests import json class RestaurantSearch(BaseRapidAPITool): def __init__(self): super().__init__() self.url = "https://tripadvisor16.p.rapidapi.com/api/v1/restaurant/searchRestaurants" self.host_name = "tripadvisor16.p.rapidapi.com" self.api_key = get_from_env("RAPID_API_KEY") def run(self, params: dict): headers = { "X-RapidAPI-Key": self.api_key, "X-RapidAPI-Host": self.host_name } try: self.query_string = { "locationId": params["locationId"] } except ValueError: raise KeyError( "The keys in params do not match the excepted keys in params for tripadvisor search restaurant api. " "Please make sure it contains following required keys: " "locationID", ) response = requests.get(self.url, headers=headers, params=self.query_string).json() return self.parse_result(response) def parse_result(self, response) -> str: limited_results = response['data']['data'][:2] simplified_results = [] for result in limited_results: simplified_result = { 'restaurantsId': result['restaurantsId'], 'name': result['name'], 'averageRating': result['averageRating'], 'userReviewCount': result['userReviewCount'], 'priceTag': result['priceTag'], 'establishmentTypeAndCuisineTags': result['establishmentTypeAndCuisineTags'] } simplified_results.append(simplified_result) return json.dumps(simplified_results) def get_tool_call_format(self): tool_call_format = { "type": "function", "function": { "name": "restaurant_search", "description": "Search for a restaurant by locationID", "parameters": { "type": "object", "properties": { "locationId ": { "type": "string", "description": "The locationID of the restaurant to search for" } }, "required": [ "locationId" ] } } } return tool_call_format ================================================ FILE: pyopenagi/tools/wikipedia/wikipedia.py ================================================ from ..base import BaseTool # from langchain_core.documents import Document from typing import Optional, Any class Wikipedia(BaseTool): """Wikipedia tool, refactored from langchain. To use, you should have the ``wikipedia`` python package installed. This wrapper will use the Wikipedia API to conduct searches and fetch page summaries. By default, it will return the page summaries of the top-k results. It limits the Document content by doc_content_chars_max. """ def __init__(self): super().__init__() self.WIKIPEDIA_MAX_QUERY_LENGTH = 300 self.top_k_results = 3 self.lang = "en" self.load_all_available_meta: bool = False self.doc_content_chars_max: int = 4000 self.wiki_client = self.build_client() def build_client(self): try: import wikipedia wikipedia.set_lang(self.lang) except ImportError: raise ImportError( "Could not import wikipedia python package. " "Please install it with `pip install wikipedia`." ) return wikipedia def run(self, params) -> str: """Run Wikipedia search and get page summaries.""" query = params["query"] # if not isinstance(query, dict) or 'query' not in query: # raise TypeError("Query must be a dictionary with a 'query' key") # query_str = query['query'][:self.WIKIPEDIA_MAX_QUERY_LENGTH] # Extract and slice the query string page_titles = self.wiki_client.search(query, results=self.top_k_results) summaries = [] for page_title in page_titles[: self.top_k_results]: if wiki_page := self._fetch_page(page_title): if summary := self._formatted_page_summary(page_title, wiki_page): summaries.append(summary) if not summaries: return "No good Wikipedia Search Result was found" return "\n\n".join(summaries)[: self.doc_content_chars_max] @staticmethod def _formatted_page_summary(page_title: str, wiki_page: Any) -> Optional[str]: return f"Page: {page_title}\nSummary: {wiki_page.summary}" def get_tool_call_format(self): tool_call_format = { "type": "function", "function": { "name": "wikipedia", "description": "Provides relevant information about the destination", "parameters": { "type": "object", "properties": { "query": { "type": "string", "description": "Search query for Wikipedia" } }, "required": [ "query" ] } } } return tool_call_format ================================================ FILE: pyopenagi/tools/wolfram/wolfram_alpha.py ================================================ from ..base import BaseTool from pyopenagi.utils.utils import get_from_env class WolframAlpha(BaseTool): """Wolfram Alpha Tool, refactored from langchain. Docs for using: 1. Go to wolfram alpha and sign up for a developer account 2. Create an app and get your APP ID 3. Save your APP ID into WOLFRAM_ALPHA_APPID env variable 4. pip install wolframalpha """ def __init__(self): super().__init__() self.wolfram_alpha_appid = get_from_env("WOLFRAM_ALPHA_APPID") self.wolfram_client = self.build_client() def build_client(self): try: import wolframalpha except ImportError: raise ImportError( "wolframalpha is not installed. " "Please install it with `pip install wolframalpha`" ) client = wolframalpha.Client(self.wolfram_alpha_appid) return client def run(self, query: str) -> str: """Run query through WolframAlpha and parse result.""" res = self.wolfram_client.query(query) try: assumption = next(res.pods).text answer = next(res.results).text except StopIteration: return "Wolfram Alpha wasn't able to answer it" if answer is None or answer == "": # We don't want to return the assumption alone if answer is empty return "No good Wolfram Alpha Result was found" else: return f"Assumption: {assumption} \nAnswer: {answer}" def get_tool_call_format(self): tool_call_format = { "type": "function", "function": { "name": "wolfram_alpha", "description": "Use specific mathematical knowledge (algebra, calculus, geometry, etc) to answer the given query", "parameters": { "type": "object", "properties": { "query": { "type": "string", "description": "the abstracted mathematical query that needs to be answered" } }, "required": [ "query" ] } } } return tool_call_format ================================================ FILE: pyopenagi/tools/words_api/words_api.py ================================================ from ..base import BaseRapidAPITool # from pydantic import root_validator from pyopenagi.utils.utils import get_from_env import requests SUPPORTED_APIS = [ "typeOf", "hasTypes", "partOf", "hasParts", "instanceOf", "hasInstances", "similarTo", "also", "entails", "memberOf", "hasMembers", "substanceOf", "hasSubstances", "inCategory", "hasCategories", "usageOf", "hasUsages", "inRegion", "regionOf", "pertainsTo", "synonyms", "examples", "antonyms", "pronunciation", ] class WordsAPI(BaseRapidAPITool): def __init__(self): super().__init__() self.base_url = "https://wordsapiv1.p.rapidapi.com/words/" self.url = self.base_url self.host_name = "wordsapiv1.p.rapidapi.com" self.api_key = get_from_env("RAPID_API_KEY") def run(self, params): headers = { "X-RapidAPI-Key": self.api_key, "X-RapidAPI-Host": self.host_name } try: self.word = params["word"] self.api_name = params["api_name"] except KeyError: raise KeyError( "The keys in params do not match the excepted keys in params for words api. " "Please make sure it contains two keys: 'words' and 'api_name'" ) if not self.is_supported(self.api_name): raise ValueError( f"{self.api_name} is currently not supported!" ) self.url = f"{self.base_url}{self.word}/{self.api_name}" response = requests.get(self.url, headers=headers).json() result = self.parse_result(response) return result def parse_result(self, response) -> str: # fail response: {'success': False, 'message': 'word not found'} if "success" in response and not response["success"]: return response["message"] return response["word"] + " " + self.api_name + " [" + ",".join(response[self.api_name]) + "]" def is_supported(self, api_name): return api_name in SUPPORTED_APIS ================================================ FILE: pyopenagi/utils/README.md ================================================ # pyopenagi/utils Helper utils that are re-used in AIOS. These are various tools that we use in our internal implementations. In the future they shouldn't be copy pasted to AIOS. ================================================ FILE: pyopenagi/utils/__init__.py ================================================ ================================================ FILE: pyopenagi/utils/chat_template.py ================================================ class Query: def __init__(self, messages, tools = None, message_return_type = "text" ) -> None: """Query format Args: messages (list): [ {"role": "xxx", content_key: content_value} ] tools (optional): tools that are used for function calling. Defaults to None. """ self.messages = messages self.tools = tools self.message_return_type = message_return_type class Response: def __init__( self, response_message, tool_calls: list = None ) -> None: """Response format Args: response_message (str): "generated_text" tool_calls (list, optional): [ {"name": "xxx", "parameters": {}} ]. Default to None. """ self.response_message = response_message self.tool_calls = tool_calls ================================================ FILE: pyopenagi/utils/commands/top.py ================================================ ================================================ FILE: pyopenagi/utils/compressor.py ================================================ import zlib class Compressor: def __init__(self) -> None: pass def compress(self, data): pass def decompress(self, compressed_data): pass class ZLIBCompressor(Compressor): def __init__(self) -> None: pass def compress(self, data): compressed_data = zlib.compress(data.encode('utf-8')) return compressed_data def decompress(self, compressed_data): decompressed_data = zlib.decompress(compressed_data) return decompressed_data.decode('utf-8') ================================================ FILE: pyopenagi/utils/logger.py ================================================ import click import os from datetime import datetime class BaseLogger: def __init__(self, logger_name, log_mode = "console", ) -> None: self.logger_name = logger_name self.log_mode = log_mode self.log_file = self.load_log_file() if log_mode == "file" else None self.level_color = dict() def log(self, content, level): if self.log_mode == "console": self.log_to_console(content, level) else: assert self.log_mode == "file" and self.log_file is not None self.log_to_file(content, self.log_file) def load_log_file(self): pass def log_to_console(self, content, level): # print(content) click.secho(f"[{self.logger_name}] " + content, fg=self.level_color[level]) def log_to_file(self, content, log_file): with open(log_file, "a") as w: w.writelines(content) class SchedulerLogger(BaseLogger): def __init__(self, logger_name, log_mode="console") -> None: super().__init__(logger_name, log_mode) self.level_color = { "execute": "green", "suspend": "yellow", "info": "white" } def load_log_file(self): date_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") log_dir = os.path.join(os.getcwd(), "logs", "scheduler") if not os.path.exists(log_dir): os.makedirs(log_dir) log_file = os.path.join(log_dir, f"{date_time}.txt") return log_file class AgentLogger(BaseLogger): def __init__(self, logger_name, log_mode="console") -> None: super().__init__(logger_name, log_mode) self.level_color = { "info": (248, 246, 227), # white "executing": (217, 237, 191), # green "suspending": (255, 235, 178), # yellow "done": (122, 162, 227) # blue } def load_log_file(self): date_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") log_dir = os.path.join(os.getcwd(), "logs", "agents", self.logger_name) if not os.path.exists(log_dir): os.makedirs(log_dir) log_file = os.path.join(log_dir, f"{date_time}.txt") return log_file class LLMKernelLogger(BaseLogger): def __init__(self, logger_name, log_mode="console") -> None: super().__init__(logger_name, log_mode) self.level_color = { "info": (246, 245, 242), "executing": (65, 176, 110), # green "suspending": (255, 201, 74), # yellow "done": (122, 162, 227) # blue } def log_to_console(self, content, level): # print(content) click.secho(f"[\U0001F916{self.logger_name}] " + content, fg=self.level_color[level], bold=True) def load_log_file(self): date_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") log_dir = os.path.join(os.getcwd(), "logs", "llm_kernel", self.logger_name) if not os.path.exists(log_dir): os.makedirs(log_dir) log_file = os.path.join(log_dir, f"{date_time}.txt") return log_file ================================================ FILE: pyopenagi/utils/utils.py ================================================ import argparse import os import shutil import json from typing import Dict, Any, Optional import re # logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') # logger = logging.getLogger(__name__) def parse_global_args(): parser = argparse.ArgumentParser(description="Parse global parameters") parser.add_argument('--llm_name', type=str, default="gpt-4o-mini", help="Specify the LLM name of AIOS") parser.add_argument('--max_gpu_memory', type=json.loads, help="Max gpu memory allocated for the LLM") parser.add_argument('--eval_device', type=str, help="Evaluation device") parser.add_argument('--max_new_tokens', type=int, default=256, help="The maximum number of new tokens for generation") parser.add_argument("--llm_kernel_log_mode", type=str, default="console", choices=["console", "file"]) parser.add_argument("--use_backend", type=str, default="ollama", choices=["ollama", "vllm"]) return parser def extract_before_parenthesis(s: str) -> str: match = re.search(r'^(.*?)\([^)]*\)', s) return match.group(1) if match else s def get_from_dict_or_env( data: Dict[str, Any], key: str, env_key: str, default: Optional[str] = None ) -> str: """Get a value from a dictionary or an environment variable.""" if key in data and data[key]: return data[key] else: return get_from_env(key, env_key, default=default) def get_from_env(env_key: str, default: Optional[str] = None) -> str: """Get a value from an environment variable.""" if env_key in os.environ and os.environ[env_key]: return os.environ[env_key] elif default is not None: return default else: raise ValueError( f"Did not find {env_key}, please add an environment variable" f" `{env_key}` which contains it. " ) class Logger: def __init__(self, log_mode) -> None: self.log_mode = log_mode def log(self, info, path=None): if self.log_mode == "console": print(info) else: assert self.log_mode == "file" with open(path, "w") as w: w.write(info + "\n") def delete_directories(root_dir, target_dirs): """ Recursively deletes directories with names in target_dirs starting from root_dir. """ for dirpath, dirnames, filenames in os.walk(root_dir, topdown=False): for dirname in dirnames: if dirname in target_dirs: full_path = os.path.join(dirpath, dirname) # print(f"Deleting {full_path}...") shutil.rmtree(full_path, ignore_errors=True) ================================================ FILE: pyproject.toml ================================================ [build-system] build-backend = "hatchling.build" requires = ["hatchling", "hatch-requirements-txt"] [project] dynamic = ["dependencies"] description = "OpenAGI: Package for AI Agent Creation" keywords = ["llm", "agi"] license = {file = "LICENSE"} name = "pyopenagi" readme = "README.md" requires-python = ">=3.9" version = "0.0.11" classifiers = [ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", "Topic :: Software Development :: Libraries :: Python Modules", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", ] [project.urls] Homepage = "https://github.com/agiresearch/OpenAGI" Repository = "https://github.com/agiresearch/OpenAGI.git" "Tools Docs" = "https://github.com/agiresearch/OpenAGI/tools.md" [tool.hatch.build] exclude = ["research/", "pyopenagi.egg-info/", "dist", "__pycache__/", ".pytest_cache/"] [tool.hatch.metadata.hooks.requirements_txt] files = ["requirements.txt"] [tool.hatch.build.targets.wheel] packages = ["pyopenagi"] ================================================ FILE: requirements-dev.txt ================================================ -r requirements.txt pre-commit pytest ================================================ FILE: requirements.txt ================================================ python-dotenv Requests Pympler==1.0.1 click==8.1.7 python-dotenv==1.0.0 beautifulsoup4 playwright ================================================ FILE: tests/README.md ================================================ # tests This directory contains tests you can use to test specific features of the project so you can figure out which specific parts work easier. For example, test_agent_creation.py simply tests the AgentProcess ability to hold agents. We want to use error code to differentiate between successful and failed tests in the future. ================================================ FILE: tests/__init__.py ================================================ ================================================ FILE: tests/test_agent_creation.py ================================================ # make sure we can create agents from pyopenagi.agents.agent_process import AgentProcess from pyopenagi.utils.chat_template import Query def test_agent_creation(): agent_process = AgentProcess( agent_name="example/academic_agent", query=Query( messages = [ {"role": "user", "content": "Summarize researches of quantum computing in recent five years."} ] ) ) # Use plain assert statements for testing conditions assert agent_process.agent_name == "example/academic_agent", "Agent name does not match" # Add more assertions here as necessary to validate the properties of the agent_process object ================================================ FILE: tests/test_tools/README.md ================================================ # test/test_tools This tests specific tools the agents can use and makes sure they are working. Each tool has its own test. ================================================ FILE: tests/test_tools/test_currency_converter.py ================================================ import os import pytest from pyopenagi.tools.currency_converter.currency_converter import CurrencyConverter from dotenv import load_dotenv, find_dotenv @pytest.fixture(scope="module") def test_rapid_api_key(): load_dotenv(find_dotenv()) if "RAPID_API_KEY" not in os.environ or not os.environ["RAPID_API_KEY"]: with pytest.raises(ValueError): CurrencyConverter() pytest.skip("Rapid api key is not set.") else: return True @pytest.mark.usefixtures("test_rapid_api_key") def test_currency_converter_api(): load_dotenv(find_dotenv()) currency_converter_api = CurrencyConverter() params = { "from": "USD", "to": "EUR", "amount": 2 } result = currency_converter_api.run(params=params) print(result) assert isinstance(result, str) ================================================ FILE: tests/test_tools/test_top_series.py ================================================ import os import pytest import requests from requests.models import Response import json from pyopenagi.tools.imdb.top_series import TopSeries from dotenv import load_dotenv, find_dotenv @pytest.fixture(scope="module") def test_rapid_api_key(): load_dotenv(find_dotenv()) if "RAPID_API_KEY" not in os.environ or not os.environ["RAPID_API_KEY"]: with pytest.raises(ValueError): TopSeries() pytest.skip("RAPID api key is not set.") else: return True class ImdbTopSeriesMock: @staticmethod def json(): mock_items = [] mock_title = "Mock Title" mock_description = "Mock Description." mock_image = "https://m.media-amazon.com/images/Mock/Standard.Image.jpg" mock_big_image = "https://m.media-amazon.com/images/Mock/Big.Image.jpg" mock_genre = ["Drama", "Fantasy"] mock_thumbnail = "https://m.media-amazon.com/images/Mock/Thumb.Image.jpg" mock_rating = 9.2 mock_year = "2011-2019" mock_imdbid = "tt0000000" mock_imdb_link = "https://www.imdb.com/title/tt0000000" for i in range(100): mock_items.append( { "rank": i + 1, "title": mock_title, "description": mock_description, "image": mock_image, "big_image": mock_big_image, "genre": mock_genre, "thumbnail": mock_thumbnail, "rating": mock_rating, "id": f"top{i+1}", "year": mock_year, "imdbid": mock_imdbid, "mock_imdb_link": mock_imdb_link, } ) mock_response = Response() mock_response.status_code = 200 mock_response._content = str.encode(json.dumps(mock_items)) return mock_response.json() @pytest.fixture(autouse=True) def mock_response(monkeypatch): def mock_get(*args, **kwargs): return ImdbTopSeriesMock() monkeypatch.setattr(requests, "get", mock_get) @pytest.mark.usefixtures("test_rapid_api_key") @pytest.mark.parametrize( "valid_start, valid_end", [ [1, 100], [60, 61], [60, 62], ], ) def test_top_series_api_valid_input_outputs_valid_delimiter_count( valid_start, valid_end ): load_dotenv(find_dotenv()) top_series_api = TopSeries() params = {"start": valid_start, "end": valid_end} result = top_series_api.run(params=params) assert isinstance(result, str) assert result.count(";") == max(0, int(valid_end) - int(valid_start)) @pytest.mark.usefixtures("test_rapid_api_key") def test_top_series_api_reverse_range_returns_blank(): load_dotenv(find_dotenv()) top_series_api = TopSeries() params = {"start": 100, "end": 0} result = top_series_api.run(params=params) assert result == "Top 100-0 series ranked by IMDB are: " @pytest.mark.parametrize( "invalid_start, valid_end", [ ["0", 100], [0.5, 100], [[], 100], [{}, 100] ] ) @pytest.mark.usefixtures("test_rapid_api_key") def test_top_series_api_invalid_start_type_raises_typeerror(invalid_start, valid_end): load_dotenv(find_dotenv()) top_series_api = TopSeries() params = {"start": invalid_start, "end": valid_end} with pytest.raises(TypeError): top_series_api.run(params=params) @pytest.mark.parametrize( "invalid_start, valid_end", [ [1, "0"], [1, 0.5], [1, []], [1, {}] ] ) @pytest.mark.usefixtures("test_rapid_api_key") def test_top_series_api_invalid_end_type_raises_typeerror(invalid_start, valid_end): load_dotenv(find_dotenv()) top_series_api = TopSeries() params = {"start": invalid_start, "end": valid_end} with pytest.raises(TypeError): top_series_api.run(params=params) @pytest.mark.usefixtures("test_rapid_api_key") def test_top_series_api_invalid_start_count_raises_indexerror(): load_dotenv(find_dotenv()) top_series_api = TopSeries() invalid_start = {"start": 101, "end": 102} with pytest.raises(IndexError): top_series_api.run(params=invalid_start) @pytest.mark.usefixtures("test_rapid_api_key") def test_top_series_api_invalid_end_count_raises_indexerror(): load_dotenv(find_dotenv()) top_series_api = TopSeries() invalid_end = {"start": 1, "end": 101} with pytest.raises(IndexError): top_series_api.run(params=invalid_end) ================================================ FILE: tests/test_tools/test_wolfram_alpha.py ================================================ import os import pytest from pyopenagi.tools.wolfram.wolfram_alpha import WolframAlpha from dotenv import load_dotenv, find_dotenv @pytest.fixture(scope="module") def test_wolfram_alpha_id(): load_dotenv(find_dotenv()) if "WOLFRAM_ALPHA_APPID" not in os.environ or not os.environ["WOLFRAM_ALPHA_APPID"]: with pytest.raises(ValueError): WolframAlpha() pytest.skip("WolframAlpha app id is not set.") else: return True @pytest.mark.usefixtures("test_wolfram_alpha_id") def test_wolfram_alpha(): wolfram_alpha = WolframAlpha() query = "What is the square root of 144?" result = wolfram_alpha.run(query) assert "12" in result ================================================ FILE: tests/test_tools/test_words_api.py ================================================ import os import pytest from pyopenagi.tools.words_api.words_api import WordsAPI from dotenv import load_dotenv, find_dotenv @pytest.fixture(scope="module") def test_rapid_api_key(): load_dotenv(find_dotenv()) if "RAPID_API_KEY" not in os.environ or not os.environ["RAPID_API_KEY"]: with pytest.raises(ValueError): WordsAPI() pytest.skip("Rapid api key is not set.") @pytest.mark.usefixtures("test_rapid_api_key") def test_words_api(): words_api = WordsAPI() params = { "word": "look", "api_name": "typeOf", } result = words_api.run(params=params) print(result) assert isinstance(result, str) ================================================ FILE: tools.md ================================================ # Tool Configuration ## Available tools ### Wolfram Alpha 1. Register wolfram alpha app account and activate [APP ID](https://developer.wolframalpha.com/access) 2. Setup Wolfram Alpha APP_ID ```bash export WOLFRAM_ALPHA_APPID= ``` ### Rapid API Tool 1. Register for [Rapid API](https://rapidapi.com/hub) 2. Click into the tool page that you want to call and click the (`Subscribe to Test`) button to activate tools. 3. Setup up Rapid API Key ```bash export RAPID_API_KEY= ``` #### Current supported Rapid API tools - [Words API](https://rapidapi.com/dpventures/api/wordsapi/) - [Moon Phase](https://rapidapi.com/MoonAPIcom/api/moon-phase/) - [Trip Advisor](https://rapidapi.com/DataCrawler/api/tripadvisor16) - [Shazam](https://rapidapi.com/apidojo/api/shazam/) - [IMDB](https://rapidapi.com/rapihub-rapihub-default/api/imdb-top-100-movies/)