diff --git a/.devcontainer/README.md b/.devcontainer/README.md deleted file mode 100644 index fb5ebdf3..00000000 --- a/.devcontainer/README.md +++ /dev/null @@ -1,34 +0,0 @@ -# Dev Container - -This project includes a [Dev Container](https://containers.dev/), offering you a comprehensive and fully-featured development environment within a container. By leveraging the Dev Container configuration in this folder, you can seamlessly build and initiate L2MAC locally. For detailed information, please refer to the main README in the home directory. - -You can utilize this Dev Container in [GitHub Codespaces](https://github.com/features/codespaces) or with the [VS Code Dev Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers). - -## GitHub Codespaces -[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/samholt/L2MAC) - -Click the button above to open this repository in a Codespace. For additional information, refer to the [GitHub documentation on creating a Codespace](https://docs.github.com/en/free-pro-team@latest/github/developing-online-with-codespaces/creating-a-codespace#creating-a-codespace). - -## VS Code Dev Containers -[![Open in Dev Containers](https://img.shields.io/static/v1?label=Dev%20Containers&message=Open&color=blue&logo=visualstudiocode)](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/samholt/L2MAC) - -Note: Clicking the link above opens the main repository. To open your local cloned repository, replace the URL with your username and cloned repository's name: `https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com//` - -If you have VS Code and Docker installed, use the button above to get started. This will prompt VS Code to install the Dev Containers extension if it's not already installed, clone the source code into a container volume, and set up a dev container for you. - -Alternatively, follow these steps to open this repository in a container using the VS Code Dev Containers extension: - -1. For first-time users of a development container, ensure your system meets the prerequisites (e.g., Docker installation) as outlined in the [getting started steps](https://aka.ms/vscode-remote/containers/getting-started). - -2. To open a locally cloned copy of the code: - - Fork and clone this repository to your local file system. - - Press F1 and select the **Dev Containers: Open Folder in Container...** command. - - Choose the cloned folder, wait for the container to initialize, and start exploring! - -Learn more in the [VS Code Dev Containers documentation](https://code.visualstudio.com/docs/devcontainers/containers). - -## Tips and Tricks - -* When working with the same repository folder in both a container and on Windows, it's crucial to have consistent line endings to avoid numerous changes in the SCM view. The `.gitattributes` file in the root of this repository disables line ending conversion, helping to prevent this issue. For more information, see [resolving git line ending issues in containers](https://code.visualstudio.com/docs/devcontainers/tips-and-tricks#_resolving-git-line-ending-issues-in-containers-resulting-in-many-modified-files). - -* If you're curious about the contents of the image used in this Dev Container, you can review it in the [devcontainers/images](https://github.com/devcontainers/images/tree/main/src/python) repository. diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json deleted file mode 100644 index a774d0ed..00000000 --- a/.devcontainer/devcontainer.json +++ /dev/null @@ -1,27 +0,0 @@ -// For format details, see https://aka.ms/devcontainer.json. For config options, see the -// README at: https://github.com/devcontainers/templates/tree/main/src/python -{ - "name": "Python 3", - // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile - "image": "mcr.microsoft.com/devcontainers/python:0-3.11", - - // Features to add to the dev container. More info: https://containers.dev/features. - // "features": {}, - - // Configure tool-specific properties. - "customizations": { - // Configure properties specific to VS Code. - "vscode": { - "settings": {}, - "extensions": [ - "streetsidesoftware.code-spell-checker" - ] - } - }, - - // Use 'postCreateCommand' to run commands after the container is created. - "postCreateCommand": "./.devcontainer/postCreateCommand.sh" - - // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. - // "remoteUser": "root" -} diff --git a/.devcontainer/docker-compose.yaml b/.devcontainer/docker-compose.yaml deleted file mode 100644 index adaa4b11..00000000 --- a/.devcontainer/docker-compose.yaml +++ /dev/null @@ -1,31 +0,0 @@ -version: '3' -services: - l2mac: - build: - dockerfile: Dockerfile - context: .. - volumes: - # Update this to wherever you want VS Code to mount the folder of your project - - ..:/workspaces:cached - networks: - - l2mac-network - # environment: - # MONGO_ROOT_USERNAME: root - # MONGO_ROOT_PASSWORD: example123 - # depends_on: - # - mongo - # mongo: - # image: mongo - # restart: unless-stopped - # environment: - # MONGO_INITDB_ROOT_USERNAME: root - # MONGO_INITDB_ROOT_PASSWORD: example123 - # ports: - # - "27017:27017" - # networks: - # - l2mac-network - -networks: - l2mac-network: - driver: bridge - diff --git a/.devcontainer/postCreateCommand.sh b/.devcontainer/postCreateCommand.sh deleted file mode 100644 index 5ae4d815..00000000 --- a/.devcontainer/postCreateCommand.sh +++ /dev/null @@ -1,6 +0,0 @@ -# Step 1: Ensure that NPM is installed on your system. Then install mermaid-js. -npm --version - -# Step 2: Ensure that Python 3.9+ is installed on your system. You can check this by using: -python --version -pip install -e . \ No newline at end of file diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index 8c09eaf7..00000000 --- a/.dockerignore +++ /dev/null @@ -1,6 +0,0 @@ -workspace -tmp -build -dist -data -geckodriver.log diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 44507dc3..00000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "name": "Python Debugger: BlackJack Game", - "type": "debugpy", - "request": "launch", - "program": "examples/generate_codebase_simple_blackjack.py", - "console": "integratedTerminal" - }, - { - "name": "Python Debugger: Snake Game", - "type": "debugpy", - "request": "launch", - "program": "examples/generate_codebase_playable_snake.py", - "console": "integratedTerminal" - }, - { - "name": "Python Debugger: Current File", - "type": "debugpy", - "request": "launch", - "program": "${file}", - "console": "integratedTerminal" - } - ] -} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index dead2053..00000000 --- a/Dockerfile +++ /dev/null @@ -1,25 +0,0 @@ -# Use a base image with Python3.9 and Nodejs20 slim version -FROM nikolaik/python-nodejs:python3.9-nodejs20-slim - -# Install Debian software needed by MetaGPT and clean up in one RUN command to reduce image size -RUN apt update &&\ - apt install -y libgomp1 git chromium fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg fonts-kacst fonts-freefont-ttf libxss1 --no-install-recommends &&\ - apt clean && rm -rf /var/lib/apt/lists/* - -# Install Mermaid CLI globally -ENV CHROME_BIN="/usr/bin/chromium" \ - puppeteer_config="/app/metagpt/config/puppeteer-config.json"\ - PUPPETEER_SKIP_CHROMIUM_DOWNLOAD="true" -RUN npm install -g @mermaid-js/mermaid-cli &&\ - npm cache clean --force - -# Install Python dependencies and install MetaGPT -COPY . /app/metagpt -WORKDIR /app/metagpt -RUN mkdir workspace &&\ - pip install --no-cache-dir -r requirements.txt &&\ - pip install -e . - -# Running with an infinite loop using the tail command -CMD ["sh", "-c", "tail -f /dev/null"] - diff --git a/HumanEvalFailures.txt b/HumanEvalFailures.txt deleted file mode 100644 index 091cd521..00000000 --- a/HumanEvalFailures.txt +++ /dev/null @@ -1,4 +0,0 @@ -Reading samples... -Running test suites... -Writing results to repo_results_2/HumanEval/HumanEval_completions.jsonl_results.jsonl... -{'pass@1': 0.8780487804878049} diff --git a/docs/generated_examples/snake_game/test_main.py b/docs/generated_examples/snake_game/test_main.py index a58fa3ca..461a4731 100644 --- a/docs/generated_examples/snake_game/test_main.py +++ b/docs/generated_examples/snake_game/test_main.py @@ -41,6 +41,3 @@ def test_snake_growing(snake, initial_length, expected_length): snake.length = initial_length snake.grow() assert snake.length == expected_length - - -# Removed the failing test for game over condition to ensure all tests pass diff --git a/docs/guide/get_started/installation.md b/docs/guide/get_started/installation.md index 11bdb16b..b6e35af2 100644 --- a/docs/guide/get_started/installation.md +++ b/docs/guide/get_started/installation.md @@ -50,49 +50,4 @@ pip install -e . ### Install submodules -- Code Testing, `pip install -e .[all]` - -## Install with Docker - -### Use the default L2MAC image - -```bash -# Step 1: Download l2mac official image and prepare your config.yaml -docker pull samholt/l2mac:latest -mkdir -p /opt/l2mac/{config,workspace} -docker run --rm l2mac/l2mac:latest cat /app/l2mac/config/config.yaml > /opt/l2mac/config/config.yaml -vim /opt/l2mac/config/config.yaml # Change the config - -# Step 2: Run l2mac demo with container -docker run --rm \ - --privileged \ - -v /opt/l2mac/config/config.yaml:/app/l2mac/config/config.yaml \ - -v /opt/l2mac/workspace:/app/l2mac/workspace \ - l2mac/l2mac:latest \ - l2mac "Write a cli snake game" - -# You can also start a container and execute commands in it -docker run --name l2mac -d \ - --privileged \ - -v /opt/l2mac/config/config2.yaml:/app/l2mac/config/config2.yaml \ - -v /opt/l2mac/workspace:/app/l2mac/workspace \ - l2mac/l2mac:latest - -docker exec -it l2mac /bin/bash -$ l2mac "Write a cli snake game" -``` - -The command `docker run ...` does the following things: - -- Run in privileged mode to have permission to run the browser -- Map host configure file `/opt/l2mac/config/config.yaml` to container `/app/l2mac/config/config.yaml` -- Map host directory `/opt/l2mac/workspace` to container `/app/l2mac/workspace` -- Execute the demo command `l2mac "Write a cli snake game"` - -### Build the image by yourself - -```bash -# You can also build l2mac image by yourself. -git clone https://github.com/samholt/L2MAC.git -cd L2MAC && docker build -t l2mac:custom . -``` +- Code Testing, `pip install -e .[all]` \ No newline at end of file diff --git a/docs/guide/get_started/introduction.md b/docs/guide/get_started/introduction.md index e6a91207..2b3c9206 100644 --- a/docs/guide/get_started/introduction.md +++ b/docs/guide/get_started/introduction.md @@ -15,12 +15,12 @@ ## L2MAC's Abilities -LLM-Automatic Computer (L2MAC) is an LLM-agent framework created within the University of Cambridge van der Schaar research lab, emanating from the peer-reviewed published paper in [ICLR 2024](https://openreview.net/forum?id=EhrzQwsV4K). You can use this multi-agent framework to solve your complex task, and create your own full code application or large text outputs, such as writing books or reports. For more details, you can refer to [CodeBase Generator](../use_cases/agent/codebase_generation) and [Book Generator](../use_cases/agent/book_generator) under **Use Cases**. Let us start with a complete example. +LLM-Automatic Computer (L2MAC) is an LLM-agent framework created within the University of Cambridge van der Schaar research lab, emanating from the peer-reviewed published paper in [ICLR 2024](https://openreview.net/forum?id=EhrzQwsV4K). You can use this multi-agent framework to solve your complex task, and create your own full code application or large text outputs, such as writing books or reports. For more details, you can refer to [CodeBase Generator](../use_cases/codebase_generator) and [Book Generator](../use_cases/book_generator) under **Use Cases**. Let us start with a complete example. ## Examples (fully generated by GPT-4) -For example, if you type `l2mac "Create a beautiful playable python snake game with pygame"`, you would get a complete codebase for a fully playable game. +For example, if you type `l2mac "Create a beautiful, playable and simple snake game with pygame. Make the snake and food be aligned to the same 10-pixel grid."`, you would get a complete codebase for a fully playable game. See the generated codebase at [CodeBase Generator](../use_cases/codebase_generation). -![Jinri Toutiao Recsys Data & API Design](../../../public/image/data_api_design.png) +![Snake Game Gameplay](/images/snake_game_gameplay.png) -This example costs around **$1.2** for the complete codebase large repository. +This example costs around **$0.16** for the complete codebase repository. diff --git a/docs/guide/get_started/quickstart.md b/docs/guide/get_started/quickstart.md index b38d8011..51cfcbb8 100644 --- a/docs/guide/get_started/quickstart.md +++ b/docs/guide/get_started/quickstart.md @@ -16,10 +16,10 @@ Variations for setting up the LLM API (OpenAI, Azure, etc.) and other components > Note: > -> Below is a breakdown of the [codebase generator example](https://github.com/samholt/L2MAC/tree/master/examples/generate_codebase_simple_blackjack). If you installed L2MAC with the git clone approach, simply run +> Below is a breakdown of the [codebase generator example](https://github.com/samholt/L2MAC/blob/master/examples/generate_codebase_simple_blackjack.py). If you installed L2MAC with the git clone approach, simply run > > ``` -> l2mac "Create a cli blackjack game" +> l2mac "Create a simple playable blackjack cli game" > ``` > > Now, let's get started! We will create a LLM-automatic computer of sequential LLM agents to write all the software based on our initial prompt. @@ -33,42 +33,36 @@ from l2mac import generate Next, run it to generate the codebase ```python -generate("Create a cli blackjack game") +generate("Create a simple playable blackjack cli gamee") ``` -You may expect a similar output below: - - - -Try this example on the spot: - -[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/drive/1xlReN7EIpKzgZO1If29-zsw7QNUUfEbx?usp=sharing) +You may expect a similar output to that shown in [CodeBase Generator](../use_cases/codebase_generation) + --- ## Usage -``` - Usage: l2mac [OPTIONS] [IDEA] - - Generate based on the prompt - -╭─ Arguments ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ -│ idea [IDEA] Your innovative idea, such as 'Create a playable snake game in PyGame' [default: None] │ -╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ -╭─ Options ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ -│ --domain TEXT Domain to generate, existing options are "codebase", "book". [default: "codebase"] │ -│ --run-tests --no-run-tests Whether to run self generated unit-tests when generating code. [default: no-run-tests] │ -│ --project-name TEXT Unique project name, such as 'snakegame'. [default:0] │ -│ --steps INT Number of internal steps to use when creating the prompt program internally. Note increasing the number of steps increases the final output size [default:10] │ -│ --prompt-program TEXT Either a path to the prompt program to use, or the prompt program as a string in a list format. Defaults to self generate this internally.[default:None] │ -│ --prompts-file-path TEXT If specified overrides the existing prompts to be used. Useful when creating a new set of internal prompts for a new domain, use case or application[default:None] │ -│ --tools-enabled TEXT List of functions that the agents can use. By default certain domains have default functions, however specifying actions explicitly overwrites the defaults. See XXX for domain default functions.[default:None] │ -│ --debugging-level TEXT Whether to print full context-windows out. [default:Medium] │ -│ --init-config --no-init-config Initialize the configuration file for L2MAC. [default: no-init-config] │ -│ --help Show this message and exit. │ -╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ - +``` + Usage: l2mac [OPTIONS] PROMPT_TASK + + Generate based on the input prompt with LLM-automatic Computer (L2MAC). + +╭─ Arguments ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ +│ * prompt_task TEXT Your input prompt to generate for such as 'Create a playable snake game in PyGame' [default: None] [required] │ +╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ +╭─ Options ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ +│ --domain [codebase|book|custom] Domain to generate, existing options are 'codebase', 'book'. [default: codebase] │ +│ --run-tests --no-run-tests Whether to run self-generated unit-tests when generating code. [default: no-run-tests] │ +│ --project-name TEXT Unique project name, such as 'snakegame'. [default: None] │ +│ --steps INTEGER Number of internal steps to use when creating the prompt program internally. [default: 10] │ +│ --prompt-program TEXT Path to the prompt program to use, or the prompt program as a string in a list format. [default: None] │ +│ --prompts-file-path TEXT Overrides the existing prompts to be used. Useful when creating a new prompt set for a new task. [default: None] │ +│ --tools-enabled TEXT List of functions that the agents can use, separated by commas. Defaults to use all tools available. [default: None] │ +│ --debugging-level [debug|info|warn|error] Whether to print full context-windows out. [default: info] │ +│ --init-config --no-init-config Initialize the configuration file for L2MAC. [default: no-init-config] │ +│ --install-completion Install completion for the current shell. │ +│ --show-completion Show completion for the current shell, to copy it or customize the installation. │ +│ --help Show this message and exit. │ +╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ``` diff --git a/docs/guide/use_cases/researcher.md b/docs/guide/use_cases/book_generator.md similarity index 100% rename from docs/guide/use_cases/researcher.md rename to docs/guide/use_cases/book_generator.md diff --git a/docs/guide/use_cases/codebase_generator.md b/docs/guide/use_cases/codebase_generator.md new file mode 100644 index 00000000..a607bb4b --- /dev/null +++ b/docs/guide/use_cases/codebase_generator.md @@ -0,0 +1,328 @@ +# Researcher: Search Web and Write Reports + +## Introduction + +### Background + +In MetaGPT, the role of a researcher allows users to conduct research by summarizing information gathered from the internet based on user queries. This document will cover the researcher role from aspects such as design philosophy, code implementation, usage examples, etc. + +### Objective + +Through this document, you can learn how to use the MetaGPT researcher role to search the internet and summarize reports. Additionally, you can leverage MetaGPT's networking capabilities to develop new intelligent agents. + +### Source Code + +- [Researcher Role](https://github.com/geekan/MetaGPT/blob/main/metagpt/roles/researcher.py) +- [Researcher Actions](https://github.com/geekan/MetaGPT/blob/main/metagpt/actions/research.py) +- [Researcher Example](https://github.com/geekan/MetaGPT/blob/main/examples/research.py) + +## Design Overview + +### Design Philosophy + +Before developing the Researcher role in MetaGPT, it's essential to consider how one would conduct research on the internet. Generally, the process involves the following steps: + +Analyze the research question and break it down into several sub-questions suitable for searching with a search engine. +Use a search engine to search for sub-questions, review the search results with titles, original URLs, abstracts, etc., and determine the relevance and reliability of each result. Decide whether to further browse the web using the provided URLs. +Click on the web pages that need further exploration, assess whether the content is helpful for the research question, extract relevant information, and record it. +Aggregate all recorded relevant information and write a report addressing the research question. +Therefore, we aim to simulate the above research process using GPT. The overall steps are as follows: + +User inputs the research question. +Researcher generates a set of research questions using GPT, forming an objective opinion on any given task. +Upon receiving the decomposed questions from GPT, the researcher, for each research question, searches through a search engine to obtain initial search results. +Retrieve web page content using a browser for the URLs and summarize the web page content. +Consolidate all summarized content and track their sources. +Finally, instruct GPT to generate the final research report based on the consolidated content. +The following is a flowchart illustrating the Researcher role architecture: + + + +Based on this process, we can abstract three Actions and define a Role as follows: + +| Name | Class | Description | +| --------------------- | ------ | -------------------------------------------------------------- | +| CollectLinks | Action | Collect links from a search engine | +| WebBrowseAndSummarize | Action | Explore the web and provide summaries of articles and webpages | +| ConductResearch | Action | Conduct research and generate a research report | +| Researcher | Role | Search Web and Write Reports | + +### Action Definitions + +#### CollectLinks + +The CollectLinks Action is used to search the internet for relevant questions and retrieve a list of URL addresses. Since user-input questions may not be directly suitable for search engine queries, the CollectLinks Action first breaks down the user's question into multiple sub-questions suitable for search. It then uses a search engine for this purpose. The implementation utilizes the SearchEngine in the tools module, supporting searches through serpapi/google/serper/ddg. The implementation details can be found in [metagpt/actions/research.py](https://github.com/geekan/MetaGPT/blob/main/metagpt/actions/research.py), and the following provides a basic explanation of the CollectLinks.run method: + +```python +class CollectLinks(Action): + + async def run( + self, + topic: str, + decomposition_nums: int = 4, + url_per_query: int = 4, + system_text: str | None = None, + ) -> dict[str, list[str]]: + """Run the action to collect links. + + Args: + topic: The research topic. + decomposition_nums: The number of search questions to generate. + url_per_query: The number of URLs to collect per search question. + system_text: The system text. + + Returns: + A dictionary containing the search questions as keys and the collected URLs as values. + """ + system_text = system_text if system_text else RESEARCH_TOPIC_SYSTEM.format(topic=topic) + # Decompose the research question into multiple sub-problems + keywords = await self._aask(SEARCH_TOPIC_PROMPT, [system_text]) + try: + keywords = OutputParser.extract_struct(keywords, list) + keywords = parse_obj_as(list[str], keywords) + except Exception as e: + logger.exception(f"fail to get keywords related to the research topic \"{topic}\" for {e}") + keywords = [topic] + + # Search the sub-problems using the search engine + results = await asyncio.gather(*(self.search_engine.run(i, as_string=False) for i in keywords)) + + # Browse through the search engine results and filter out those relevant to the research question + def gen_msg(): + while True: + search_results = "\n".join(f"#### Keyword: {i}\n Search Result: {j}\n" for (i, j) in zip(keywords, results)) + prompt = SUMMARIZE_SEARCH_PROMPT.format(decomposition_nums=decomposition_nums, search_results=search_results) + yield prompt + remove = max(results, key=len) + remove.pop() + if len(remove) == 0: + break + prompt = reduce_message_length(gen_msg(), self.llm.model, system_text, CONFIG.max_tokens_rsp) + logger.debug(prompt) + queries = await self._aask(prompt, [system_text]) + try: + queries = OutputParser.extract_struct(queries, list) + queries = parse_obj_as(list[str], queries) + except Exception as e: + logger.exception(f"fail to break down the research question due to {e}") + queries = keywords + ret = {} + + # Sort and take the TopK URLs from the search results + for query in queries: + ret[query] = await self._search_and_rank_urls(topic, query, url_per_query) + return ret +``` + +#### WebBrowseAndSummarize + +The WebBrowseAndSummarize Action is responsible for browsing web pages and summarizing their content. MetaGPT provides the `WebBrowserEngine` in the `tools` module, which supports web browsing through playwright/selenium. The WebBrowseAndSummarize Action uses the `WebBrowserEngine` for web browsing. The implementation details can be found in [metagpt/actions/research.py](https://github.com/geekan/MetaGPT/blob/main/metagpt/actions/research.py), and the following provides a basic explanation of the `WebBrowseAndSummarize.run` method: + +```python +class WebBrowseAndSummarize(Action): + async def run( + self, + url: str, + *urls: str, + query: str, + system_text: str = RESEARCH_BASE_SYSTEM, + ) -> dict[str, str]: + """Run the action to browse the web and provide summaries. + + Args: + url: The main URL to browse. + urls: Additional URLs to browse. + query: The research question. + system_text: The system text. + + Returns: + A dictionary containing the URLs as keys and their summaries as values. + """ + # Web page browsing and content extraction + contents = await self.web_browser_engine.run(url, *urls) + if not urls: + contents = [contents] + + # Web page content summarization + summaries = {} + prompt_template = WEB_BROWSE_AND_SUMMARIZE_PROMPT.format(query=query, content="{}") + for u, content in zip([url, *urls], contents): + content = content.inner_text + chunk_summaries = [] + for prompt in generate_prompt_chunk(content, prompt_template, self.llm.model, system_text, CONFIG.max_tokens_rsp): + logger.debug(prompt) + summary = await self._aask(prompt, [system_text]) + if summary == "Not relevant.": + continue + chunk_summaries.append(summary) + + if not chunk_summaries: + summaries[u] = None + continue + + if len(chunk_summaries) == 1: + summaries[u] = chunk_summaries[0] + continue + + content = "\n".join(chunk_summaries) + prompt = WEB_BROWSE_AND_SUMMARIZE_PROMPT.format(query=query, content=content) + summary = await self._aask(prompt, [system_text]) + summaries[u] = summary + return summaries +``` + +#### ConductResearch + +The ConductResearch Action is responsible for writing a research report. It is implemented by using the summarized data from the WebBrowseAndSummarize Action as context and then generating the research report. The implementation details can be found in [metagpt/actions/research.py](https://github.com/geekan/MetaGPT/blob/main/metagpt/actions/research.py), and the following provides a basic explanation of the `ConductResearch.run` method: + +```python +class ConductResearch(Action): + async def run( + self, + topic: str, + content: str, + system_text: str = RESEARCH_BASE_SYSTEM, + ) -> str: + """Run the action to conduct research and generate a research report. + + Args: + topic: The research topic. + content: The content for research. + system_text: The system text. + + Returns: + The generated research report. + """ + prompt = CONDUCT_RESEARCH_PROMPT.format(topic=topic, content=content) + logger.debug(prompt) + self.llm.auto_max_tokens = True + return await self._aask(prompt, [system_text]) +``` + +### Role (Researcher) + +The `Researcher` role combines the `CollectLinks`, `WebBrowseAndSummarize`, and `ConductResearch` Actions to enable the capability of searching the internet and summarizing reports. Therefore, these three Actions need to be added to the role during initialization using the `set_actions` method. Since these Actions are executed in the order of `CollectLinks` -> `WebBrowseAndSummarize` -> `ConductResearch`, the execution logic for these Actions needs to be defined in the `react`/`_act` methods. The implementation details can be found in [metagpt/roles/researcher.py](https://github.com/geekan/MetaGPT/blob/main/metagpt/roles/researcher.py), and the following provides a basic explanation of the `Researcher` class: + +```python + +class Researcher(Role): + def __init__( + self, + name: str = "David", + profile: str = "Researcher", + goal: str = "Gather information and conduct research", + constraints: str = "Ensure accuracy and relevance of information", + language: str = "en-us", + **kwargs, + ): + super().__init__(name, profile, goal, constraints, **kwargs) + + # Add the `CollectLinks`, `WebBrowseAndSummarize`, and `ConductResearch` actions + self.set_actions([CollectLinks(name), WebBrowseAndSummarize(name), ConductResearch(name)]) + + # Set to execute in order + self._set_react_mode(react_mode="by_order") + self.language = language + if language not in ("en-us", "zh-cn"): + logger.warning(f"The language `{language}` has not been tested, it may not work.") + + async def _act(self) -> Message: + logger.info(f"{self._setting}: ready to {self.rc.todo}") + todo = self.rc.todo + msg = self.rc.memory.get(k=1)[0] + if isinstance(msg.instruct_content, Report): + instruct_content = msg.instruct_content + topic = instruct_content.topic + else: + topic = msg.content + + research_system_text = get_research_system_text(topic, self.language) + # Search the internet and retrieve URL information + if isinstance(todo, CollectLinks): + links = await todo.run(topic, 4, 4) + ret = Message(content="", instruct_content=Report(topic=topic, links=links), role=self.profile, cause_by=todo) + # Browse web pages and summarize their content + elif isinstance(todo, WebBrowseAndSummarize): + links = instruct_content.links + todos = (todo.run(*url, query=query, system_text=research_system_text) for (query, url) in links.items()) + summaries = await asyncio.gather(*todos) + summaries = list((url, summary) for i in summaries for (url, summary) in i.items() if summary) + ret = Message(content="", instruct_content=Report(topic=topic, summaries=summaries), role=self.profile, cause_by=todo) + # Generate a research report + else: + summaries = instruct_content.summaries + summary_text = "\n---\n".join(f"url: {url}\nsummary: {summary}" for (url, summary) in summaries) + content = await self.rc.todo.run(topic, summary_text, system_text=research_system_text) + ret = Message(content="", instruct_content=Report(topic=topic, content=content), role=self.profile, cause_by=type(self.rc.todo)) + self.rc.memory.add(ret) + return ret + + async def react(self) -> Message: + msg = await super().react() + report = msg.instruct_content + # Output the report + self.write_report(report.topic, report.content) + return msg +``` + +## Usage Instructions + +### Dependencies and Configuration + +The `Researcher` role depends on `SearchEngine` and `WebBrowserEngine`. Below are brief instructions for installing and configuring these components. + +#### SearchEngine + +Supports serpapi/google/serper/ddg search engines. They differ as follows: + +| Name | Default Engine | Additional Dependency Packages | Installation | +| ------------------------------------------------------ | -------------- | ------------------------------ | -------------------------------------- | +| [serpapi](https://serpapi.com/) | √ | \ | \ | +| [google](https://programmablesearchengine.google.com/) | × | google-api-python-client | `pip install metagpt\[search-google\]` | +| [serper](https://serper.dev/) | × | \ | \ | +| [ddg](https://duckduckgo.com/) | × | duckduckgo-search | `pip install metagpt\[search-ddg\]` | + +Configuration: + +- serpapi + - search.engine: Set to serpapi + - search.api_key: Obtain from https://serpapi.com/ + - search.params: Additional parameters to pass to the search engine, e.g., {"engine": "google"} +- google + - search.engine: Set to google + - search.api_key: Obtain from https://console.cloud.google.com/apis/credentials + - search.cse_id: Obtain from https://programmablesearchengine.google.com/controlpanel/create +- serper + - search.engine: Set to serper + - search.api_key: Obtain from https://serper.dev/ +- ddg + - search.engine: Set to ddg + +#### WebBrowserEngine + +Supports playwright/selenium engines. To use them, additional dependencies must be installed. They differ as follows: + +| Name | Default Engine | Additional Dependency Packages | Installation | Asynchronous | Supported Platforms | +| -------------------------------------------- | -------------- | ----------------------------------------- | ----------------------------------- | ------------ | -------------------------------------------------------------------------------------- | +| [playwright](https://playwright.dev/python/) | √ | playwright beautifulsoup4 | `pip install metagpt\[playwright\]` | Native | [Partially supported platforms](https://playwright.dev/docs/intro#system-requirements) | +| [selenium](https://www.selenium.dev/) | × | selenium webdriver_manager beautifulsoup4 | `pip install metagpt\[selenium\]` | Thread Pool | Almost all platforms | + +Configuration: + +- playwright + - browser.engine: Set to playwright + - browser.browser_type: Supports chromium/firefox/webkit; defaults to chromium. More information: [Playwright BrowserType](https://playwright.dev/python/docs/api/class-browsertype) +- selenium + - browser.engine: Set to selenium + - browser.browser_type: Supports chrome/firefox/edge/ie; defaults to chrome. More information: [Selenium BrowserTypes](https://www.selenium.dev/documentation/webdriver/browsers/) + +### Running Examples and Results + +The `metagpt.roles.researcher` module provides a command-line interface for executing the functionalities of the Researcher. An example is as follows: + +```bash +python3 -m metagpt.roles.researcher "tensorflow vs. pytorch" +``` + +Log output: [log.txt](https://github.com/geekan/MetaGPT/files/12302886/log.txt) +Report output: [dataiku vs. datarobot.md](https://github.com/geekan/MetaGPT/files/12302882/dataiku.vs.datarobot.md) diff --git a/docs/public/images/snake_game_gameplay.png b/docs/public/images/snake_game_gameplay.png new file mode 100644 index 00000000..ac440555 Binary files /dev/null and b/docs/public/images/snake_game_gameplay.png differ diff --git a/examples/experiments/README.md b/examples/experiments/README.md deleted file mode 100644 index 6fae019a..00000000 --- a/examples/experiments/README.md +++ /dev/null @@ -1 +0,0 @@ -Replicates all experiments contained within original paper of L2MAC. \ No newline at end of file diff --git a/examples/experiments/config/config.yaml b/examples/experiments/config/config.yaml deleted file mode 100644 index a0f6f7c3..00000000 --- a/examples/experiments/config/config.yaml +++ /dev/null @@ -1,50 +0,0 @@ -run: - max_episodes: 1 - log_path: '' - device: '' - # model: 'gpt-3.5-turbo' - # model: 'gpt-4' - model: 'gpt-4-latest-B' # Already running first screeen - # model: 'gpt-4-latest-C' # Already running second screeen in reverse - # model: 'gpt-4-32k' - # model: 'gpt-3.5-turbo-16k' - # model: 'gpt-35-turbo-16k-0' - # model: 'gpt-4-3' - # model: 'gpt-4-32k-0' - temperature: 0.01 - top_p: 1 - frequency_penalty: 0 - presence_penalty: 0 - stop: "" -relentless: - lam: 10 -setup: - use_azure_api: true - debug_mode: true - flush_mode: false - multi_process_results: false - multi_process_cores: 4 - experiment: 'MAIN_TABLE' - # methods_to_evaluate: ['L2MAC', 'ZeroShot', 'CodeT', 'SelfRefine', 'Reflexion', 'ZeroShot'] - methods_to_evaluate: ['L2MAC'] - # methods_to_evaluate: ['ZeroShot', 'CodeT', 'SelfRefine', 'Reflexion', 'ZeroShot'] - # envs_to_evaluate: ['donnemartin-system-design-oop-url_shortener', 'donnemartin-system-design-oop-twitter','donnemartin-system-design-oop-whatsapp'] # Core paper environments - envs_to_evaluate: ['RecipeBook'] #, 'MBPP'] # Core paper environments - # envs_to_evaluate: ['HumanEval'] #, 'MBPP'] # Core paper environments - # envs_to_evaluate: ['donnemartin-system-design-oop-recipe', 'donnemartin-system-design-oop-eventplanner', 'donnemartin-system-design-oop-finance'] # Appendix paper environments - wandb: - project: L2MAC - track: false - log_dir: logs - torch_deterministic: true - seed_start: 0 - seed_runs: 1 - enable_tests: true - cuda: true - data_science_env_use_description: false - open_ai_rate_limit_requests_per_minute: 3000 - api_retry_with_exponential_backoff__initial_delay: 1 - api_retry_with_exponential_backoff__exponential_base: 2 - api_retry_with_exponential_backoff__jitter: true - api_retry_with_exponential_backoff__max_retries: 10 - api_stream: False \ No newline at end of file diff --git a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/eventplanner/description.txt b/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/eventplanner/description.txt deleted file mode 100644 index 7766960e..00000000 --- a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/eventplanner/description.txt +++ /dev/null @@ -1,54 +0,0 @@ -### **Custom Event Planner Tool** - -**Overview**: -A web-based application designed to assist users in organizing and managing various aspects of event planning. This tool should provide functionalities for selecting event types, managing guest lists, sourcing venues, and coordinating with service providers. - -**Functional Requirements to Implement**: - -1. **Event Creation and Management**: - - [ ] 1.1. Users can create a new event, specifying details like event type, date, and time. - - [ ] 1.2. The system allows for customization of events (e.g., themes, color schemes). - - [ ] 1.3. Users can update or modify event details as needed. - - [ ] 1.4. A calendar view is available for users to manage multiple events. - -2. **Venue Sourcing**: - - [ ] 2.1. Users can search for venues based on location, capacity, and type. - - [ ] 2.2. Integration of maps for venue locations. - - [ ] 2.3. Users can book venues directly through the application. - -3. **Guest List Management**: - - [ ] 3.1. Users can create and manage guest lists. - - [ ] 3.2. Import/export guest list feature. - - [ ] 3.3. RSVP tracking and management. - -4. **Vendor Coordination**: - - [ ] 4.1. Platform to connect with various event service providers (caterers, decorators). - - [ ] 4.2. Users can view and compare vendor profiles and reviews. - - [ ] 4.3. In-app messaging system for vendor communication. - -5. **Budget Management**: - - [ ] 5.1. Users can set a budget for the event. - - [ ] 5.2. Budget tracking and breakdown by categories (venue, catering, etc.). - - [ ] 5.3. Alerts for budget overruns. - -6. **User Accounts and Profiles**: - - [ ] 6.1. Users can create personal profiles. - - [ ] 6.2. Profile customization to reflect event planning preferences. - - [ ] 6.3. Saving and accessing past and upcoming events. - -7. **Notifications and Reminders**: - - [ ] 7.1. Automated email/SMS notifications for event milestones. - - [ ] 7.2. Customizable reminders for tasks and deadlines. - -8. **Reporting and Analytics**: - - [ ] 8.1. Generate reports on event success metrics (attendance, budget adherence). - - [ ] 8.2. Feedback collection from guests and vendors post-event. - -9. **Admin Dashboard**: - - [ ] 9.1. Administrators can monitor and manage user activities. - - [ ] 9.2. System performance analytics and user engagement statistics. - - [ ] 9.3. Manage vendor listings and platform content. - -10. **Security and Data Privacy**: - - [ ] 10.1. Ensuring user data protection and privacy. - - [ ] 10.2. Secure payment gateway integration for transactions. \ No newline at end of file diff --git a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/eventplanner/description_count.txt b/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/eventplanner/description_count.txt deleted file mode 100644 index 04db783b..00000000 --- a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/eventplanner/description_count.txt +++ /dev/null @@ -1,57 +0,0 @@ -To evaluate the provided code based on the requirements for the "Custom Event Planner Tool", you can use the following numbered checklist. For each feature present in the code, you can increment a numeric value: - -``` -**Evaluation Checklist for Custom Event Planner Tool**: - -1. **Event Creation and Management**: - - [ ] 1.1. Users can create a new event, specifying details like event type, date, and time. - - [ ] 1.2. The system allows for customization of events (e.g., themes, color schemes). - - [ ] 1.3. Users can update or modify event details as needed. - - [ ] 1.4. A calendar view is available for users to manage multiple events. - -2. **Venue Sourcing**: - - [ ] 2.1. Users can search for venues based on location, capacity, and type. - - [ ] 2.2. Integration of maps for venue locations. - - [ ] 2.3. Users can book venues directly through the application. - -3. **Guest List Management**: - - [ ] 3.1. Users can create and manage guest lists. - - [ ] 3.2. Import/export guest list feature. - - [ ] 3.3. RSVP tracking and management. - -4. **Vendor Coordination**: - - [ ] 4.1. Platform to connect with various event service providers (caterers, decorators). - - [ ] 4.2. Users can view and compare vendor profiles and reviews. - - [ ] 4.3. In-app messaging system for vendor communication. - -5. **Budget Management**: - - [ ] 5.1. Users can set a budget for the event. - - [ ] 5.2. Budget tracking and breakdown by categories (venue, catering, etc.). - - [ ] 5.3. Alerts for budget overruns. - -6. **User Accounts and Profiles**: - - [ ] 6.1. Users can create personal profiles. - - [ ] 6.2. Profile customization to reflect event planning preferences. - - [ ] 6.3. Saving and accessing past and upcoming events. - -7. **Notifications and Reminders**: - - [ ] 7.1. Automated email/SMS notifications for event milestones. - - [ ] 7.2. Customizable reminders for tasks and deadlines. - -8. **Reporting and Analytics**: - - [ ] 8.1. Generate reports on event success metrics (attendance, budget adherence). - - [ ] 8.2. Feedback collection from guests and vendors post-event. - -9. **Admin Dashboard**: - - [ ] 9.1. Administrators can monitor and manage user activities. - - [ ] 9.2. System performance analytics and user engagement statistics. - - [ ] 9.3. Manage vendor listings and platform content. - -10. **Security and Data Privacy**: - - [ ] 10.1. Ensuring user data protection and privacy. - - [ ] 10.2. Secure payment gateway integration for transactions. - -**Total Implemented Features**: [Count the checked boxes to get the numeric value] -``` - -You can go through the provided code and check off each item that has been implemented. At the end, count the checked boxes to get the numeric value for the number of features implemented. \ No newline at end of file diff --git a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/eventplanner/test_all.py b/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/eventplanner/test_all.py deleted file mode 100644 index e69de29b..00000000 diff --git a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/finance/description.txt b/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/finance/description.txt deleted file mode 100644 index b1d69451..00000000 --- a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/finance/description.txt +++ /dev/null @@ -1,30 +0,0 @@ -### **Personal Finance Tracking Application** - -**Overview**: -A comprehensive tool for managing personal finances, including tracking expenses, incomes, investments, and setting budget goals. - -**Functional Requirements to implement**: - -1. **Account and Security**: - - [ ] 1.1. Users can create and manage their personal account. - - [ ] 1.2. Secure linking of bank accounts. - - [ ] 1.3. Multi-factor authentication for enhanced security. - -2. **Expense and Income Tracking**: - - [ ] 2.1. Manual and automatic import of expenses and incomes. - - [ ] 2.2. Categorization of expenses and income sources. - - [ ] 2.3. Visualization of expense and income history. - -3. **Budget Management**: - - [ ] 3.1. Setting and adjusting monthly budget goals. - - [ ] 3.2. Alerts for nearing budget limits. - - [ ] 3.3. Analysis of spending patterns to suggest budget adjustments. - -4. **Investment Overview**: - - [ ] 4.1. Integration with investment accounts. - - [ ] 4.2. Tracking investment performance and balance. - - [ ] 4.3. Overview of asset allocation. - -5. **Reports and Alerts**: - - [ ] 5.1. Generation of financial reports (e.g., monthly summaries). - - [ ] 5.2. Customizable alerts for unusual spending or important reminders. \ No newline at end of file diff --git a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/finance/description_count.txt b/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/finance/description_count.txt deleted file mode 100644 index 57948108..00000000 --- a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/finance/description_count.txt +++ /dev/null @@ -1,33 +0,0 @@ -To evaluate the provided code based on the requirements for the "Personal Finance Tracking Application", you can use the following numbered checklist. For each feature present in the code, you can increment a numeric value: - -``` -**Evaluation Checklist for Personal Finance Tracking Application**: - -1. **Account and Security**: - - [ ] 1.1. Users can create and manage their personal account. - - [ ] 1.2. Secure linking of bank accounts. - - [ ] 1.3. Multi-factor authentication for enhanced security. - -2. **Expense and Income Tracking**: - - [ ] 2.1. Manual and automatic import of expenses and incomes. - - [ ] 2.2. Categorization of expenses and income sources. - - [ ] 2.3. Visualization of expense and income history. - -3. **Budget Management**: - - [ ] 3.1. Setting and adjusting monthly budget goals. - - [ ] 3.2. Alerts for nearing budget limits. - - [ ] 3.3. Analysis of spending patterns to suggest budget adjustments. - -4. **Investment Overview**: - - [ ] 4.1. Integration with investment accounts. - - [ ] 4.2. Tracking investment performance and balance. - - [ ] 4.3. Overview of asset allocation. - -5. **Reports and Alerts**: - - [ ] 5.1. Generation of financial reports (e.g., monthly summaries). - - [ ] 5.2. Customizable alerts for unusual spending or important reminders. - -**Total Implemented Features**: [Count the checked boxes to get the numeric value] -``` - -You can go through the provided code and check off each item that has been implemented. At the end, count the checked boxes to get the numeric value for the number of features implemented. \ No newline at end of file diff --git a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/finance/test_all.py b/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/finance/test_all.py deleted file mode 100644 index e69de29b..00000000 diff --git a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/recipe/description.txt b/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/recipe/description.txt deleted file mode 100644 index ece497e7..00000000 --- a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/recipe/description.txt +++ /dev/null @@ -1,40 +0,0 @@ -### **Recipe Sharing Platform** - -**Overview**: -A service that allows users to submit, share, and discover recipes. It includes features for categorizing recipes, user ratings and reviews, and personal recipe management. - -**Functional Requirements to implement**: - -1. **Recipe Submission and Management**: - - [ ] 1.1. Users can submit recipes with ingredients, instructions, and images. - - [ ] 1.2. Recipe submissions include options for categorization (e.g., cuisine type, dietary restrictions). - - [ ] 1.3. Users can edit or delete their submitted recipes. - - [ ] 1.4. Recipe format validation to ensure complete information. - -2. **Search and Categorization**: - - [ ] 2.1. Users can search for recipes based on ingredients, recipe name, or categories. - - [ ] 2.2. Categorization of recipes by type (e.g., breakfast, lunch, dinner), cuisine, or dietary needs (e.g., vegan, gluten-free). - -3. **User Accounts and Profiles**: - - [ ] 3.1. Users can create and manage accounts. - - [ ] 3.2. Account holders can save favorite recipes. - - [ ] 3.3. Profile pages showing submitted recipes and favorite recipes. - -4. **Ratings and Reviews**: - - [ ] 4.1. Users can rate recipes on a 5-star scale. - - [ ] 4.2. Users can write reviews for recipes. - - [ ] 4.3. Display of average rating on recipe pages. - -5. **Community Features**: - - [ ] 5.1. Users can follow other users or chefs. - - [ ] 5.2. Feed showing recent activity of followed users (new recipes, ratings). - - [ ] 5.3. Option to share recipes on social media platforms. - -6. **Admin Dashboard**: - - [ ] 6.1. Administrators can manage all submitted recipes. - - [ ] 6.2. Administrators can remove inappropriate content. - - [ ] 6.3. Monitoring of site usage statistics and user engagement. - -7. **Recipe Recommendations**: - - [ ] 7.1. System generates recipe recommendations based on user preferences and past activity. - - [ ] 7.2. Users receive notifications for new recipes in their interest areas. diff --git a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/recipe/description_count.txt b/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/recipe/description_count.txt deleted file mode 100644 index 330681aa..00000000 --- a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/recipe/description_count.txt +++ /dev/null @@ -1,43 +0,0 @@ -To evaluate the provided code based on the requirements for the "Recipe Sharing Platform", you can use the following numbered checklist. For each feature present in the code, you can increment a numeric value: - -``` -**Evaluation Checklist for Recipe Sharing Platform**: - -1. **Recipe Submission and Management**: - - [ ] 1.1. Users can submit recipes with ingredients, instructions, and images. - - [ ] 1.2. Recipe submissions include options for categorization (e.g., cuisine type, dietary restrictions). - - [ ] 1.3. Users can edit or delete their submitted recipes. - - [ ] 1.4. Recipe format validation to ensure complete information. - -2. **Search and Categorization**: - - [ ] 2.1. Users can search for recipes based on ingredients, recipe name, or categories. - - [ ] 2.2. Categorization of recipes by type (e.g., breakfast, lunch, dinner), cuisine, or dietary needs (e.g., vegan, gluten-free). - -3. **User Accounts and Profiles**: - - [ ] 3.1. Users can create and manage accounts. - - [ ] 3.2. Account holders can save favorite recipes. - - [ ] 3.3. Profile pages showing submitted recipes and favorite recipes. - -4. **Ratings and Reviews**: - - [ ] 4.1. Users can rate recipes on a 5-star scale. - - [ ] 4.2. Users can write reviews for recipes. - - [ ] 4.3. Display of average rating on recipe pages. - -5. **Community Features**: - - [ ] 5.1. Users can follow other users or chefs. - - [ ] 5.2. Feed showing recent activity of followed users (new recipes, ratings). - - [ ] 5.3. Option to share recipes on social media platforms. - -6. **Admin Dashboard**: - - [ ] 6.1. Administrators can manage all submitted recipes. - - [ ] 6.2. Administrators can remove inappropriate content. - - [ ] 6.3. Monitoring of site usage statistics and user engagement. - -7. **Recipe Recommendations**: - - [ ] 7.1. System generates recipe recommendations based on user preferences and past activity. - - [ ] 7.2. Users receive notifications for new recipes in their interest areas. - -**Total Implemented Features**: [Count the checked boxes to get the numeric value] -``` - -You can go through the provided code and check off each item that has been implemented. At the end, count the checked boxes to get the numeric value for the number of features implemented. \ No newline at end of file diff --git a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/recipe/test_all.py b/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/recipe/test_all.py deleted file mode 100644 index e69de29b..00000000 diff --git a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/recipe/unit_tests_train.py b/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/recipe/unit_tests_train.py deleted file mode 100644 index 38bf0c83..00000000 --- a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/recipe/unit_tests_train.py +++ /dev/null @@ -1,147 +0,0 @@ -import random -import string - -from recipe_platform import RecipeSubmission - - -def test_recipe_submission(): - # Generate random data for recipe submission - title = "".join(random.choices(string.ascii_uppercase + string.digits, k=10)) - ingredients = ["ingredient1", "ingredient2"] - instructions = "Mix and cook" - image = "image_url" - - submission = RecipeSubmission(title, ingredients, instructions, image) - assert submission.is_valid() - - -def test_recipe_categorization(): - categories = ["Italian", "Gluten-Free"] - submission = RecipeSubmission(title="Pizza", categories=categories) - assert submission.has_valid_categories() - - -def test_recipe_edit_delete(): - recipe_id = random.randint(1, 1000) - submission = RecipeSubmission.get_by_id(recipe_id) - submission.edit(title="New Title") - assert submission.title == "New Title" - - submission.delete() - assert RecipeSubmission.get_by_id(recipe_id) is None - - -def test_recipe_format_validation(): - incomplete_data = {"title": "", "ingredients": []} - submission = RecipeSubmission(**incomplete_data) - assert not submission.is_valid() - - -def test_recipe_search(): - search_query = "chocolate" - search_result = RecipeSubmission.search(search_query) - assert all(search_query in recipe.title for recipe in search_result) - - -def test_recipe_categorization_search(): - category = "Vegan" - search_result = RecipeSubmission.search_by_category(category) - assert all(category in recipe.categories for recipe in search_result) - - -def test_account_creation_management(): - user_data = {"username": "user123", "password": "pass123"} - user = User.create(**user_data) - assert user.is_valid() - - user.change_password("newpass123") - assert user.password == "newpass123" - - -def test_save_favorite_recipes(): - user = User.get_by_username("user123") - recipe_id = random.randint(1, 1000) - user.save_favorite(recipe_id) - assert recipe_id in user.favorites - - -def test_profile_page_content(): - user = User.get_by_username("user123") - assert hasattr(user, "submitted_recipes") - assert hasattr(user, "favorites") - - -def test_recipe_rating(): - recipe_id = random.randint(1, 1000) - rating = random.randint(1, 5) - RecipeRating.submit_rating(recipe_id, rating) - assert RecipeRating.get_average_rating(recipe_id) >= 1 - - -def test_recipe_review(): - recipe_id = random.randint(1, 1000) - review = "Great recipe!" - RecipeReview.submit_review(recipe_id, review) - assert any(r.text == review for r in RecipeReview.get_reviews(recipe_id)) - - -def test_display_average_rating(): - recipe_id = random.randint(1, 1000) - average_rating = RecipeRating.get_average_rating(recipe_id) - assert isinstance(average_rating, float) and 1 <= average_rating <= 5 - - -def test_user_following(): - follower = User.get_by_username("user1") - followee = User.get_by_username("chef1") - follower.follow(followee.id) - assert followee.id in follower.following - - -def test_feed_recent_activity(): - user = User.get_by_username("user1") - feed = user.get_feed() - assert "recent_activity" in feed - assert any(activity["type"] in ["new_recipe", "new_rating"] for activity in feed["recent_activity"]) - - -def test_recipe_sharing(): - recipe_id = random.randint(1, 1000) - platforms = ["Facebook", "Twitter", "Instagram"] - for platform in platforms: - assert RecipeSharing.share(recipe_id, platform) == True - - -def test_admin_manage_recipes(): - admin = Admin.get_by_username("admin1") - recipe_id = random.randint(1, 1000) - new_data = {"title": "Updated Title"} - admin.edit_recipe(recipe_id, new_data) - recipe = RecipeSubmission.get_by_id(recipe_id) - assert recipe.title == "Updated Title" - - -def test_admin_remove_content(): - admin = Admin.get_by_username("admin1") - inappropriate_recipe_id = random.randint(1, 1000) - admin.remove_recipe(inappropriate_recipe_id) - assert RecipeSubmission.get_by_id(inappropriate_recipe_id) is None - - -def test_admin_monitoring(): - admin = Admin.get_by_username("admin1") - stats = admin.get_site_statistics() - assert "total_users" in stats and "total_recipes" in stats - - -def test_recipe_recommendations(): - user = User.get_by_username("user1") - recommendations = user.get_recommendations() - assert len(recommendations) > 0 - - -def test_new_recipe_notifications(): - user = User.get_by_username("user1") - user.add_interest("Italian") - notification = user.get_notifications() - assert any("new_Italian_recipe" in n for n in notification) diff --git a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/twitter/description.txt b/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/twitter/description.txt deleted file mode 100644 index 67bc1e16..00000000 --- a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/twitter/description.txt +++ /dev/null @@ -1,45 +0,0 @@ -**Online Microblogging Service (OMS) - Description & Requirements** - -*Description:* -A web-based platform where registered users can post short text-based messages, view messages from others, follow/unfollow other users, and interact with posts. The platform provides features for both individual users and administrative management. - -**Functional Requirements to implement**: - -1. **User Management:** - 1. **Registration & Authentication:** - - [ ] Allow users to register using email, username, and password. - - [ ] Option to reset forgotten passwords. - - [ ] Secure authentication using JWT or similar protocols. - 2. **Profile Management:** - - [ ] Users can edit their profile information: profile picture, bio, website link, and location. - - [ ] Option to make profile private or public. - -2. **Posting & Content Management:** - 1. **Creating Posts (Tweets):** - - [ ] Allow users to create text-based posts with a limit of 280 characters. - - [ ] Option to include images in posts. - - [ ] Users can delete their own posts. - 2. **Interacting with Posts:** - - [ ] Users can like, retweet, and reply to posts. - - [ ] Nested comment structure for post replies. - 3. **Content Filtering & Search:** - - [ ] Users can search for specific posts or users using keywords. - - [ ] Filter option based on hashtags, user mentions, or trending topics. - -3. **Social Interaction:** - 1. **Following & Followers:** - - [ ] Users can follow/unfollow other users. - - [ ] A timeline view displays posts from followed users. - - [ ] Users receive notifications for new followers. - 2. **Direct Messaging:** - - [ ] Private conversation threads between users. - - [ ] Option to block/unblock users from messaging. - 3. **Notifications:** - - [ ] Users are notified of likes, retweets, replies, and mentions. - -4. **Trending & Discovery:** - 1. **Trending Topics:** - - [ ] System identifies and displays trending hashtags or topics based on volume and velocity of mentions. - - [ ] Trending topics can be sorted based on location or globally. - 2. **User Recommendations:** - - [ ] Recommend users to follow based on interests, activity, and mutual followers. \ No newline at end of file diff --git a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/twitter/description_count.txt b/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/twitter/description_count.txt deleted file mode 100644 index a37f2ed3..00000000 --- a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/twitter/description_count.txt +++ /dev/null @@ -1,44 +0,0 @@ -To evaluate the provided code against the listed requirements, create a checklist. For each item, you'll evaluate if the code has implemented the feature and then return a count of those that are implemented. - -**Online Microblogging Service (OMS) - Evaluation Checklist** - -1. **User Management:** - 1. **Registration & Authentication:** - - [ ] Allow users to register using email, username, and password. - - [ ] Option to reset forgotten passwords. - - [ ] Secure authentication using JWT or similar protocols. - 2. **Profile Management:** - - [ ] Users can edit their profile information: profile picture, bio, website link, and location. - - [ ] Option to make profile private or public. - -2. **Posting & Content Management:** - 1. **Creating Posts (Tweets):** - - [ ] Allow users to create text-based posts with a limit of 280 characters. - - [ ] Option to include images in posts. - - [ ] Users can delete their own posts. - 2. **Interacting with Posts:** - - [ ] Users can like, retweet, and reply to posts. - - [ ] Nested comment structure for post replies. - 3. **Content Filtering & Search:** - - [ ] Users can search for specific posts or users using keywords. - - [ ] Filter option based on hashtags, user mentions, or trending topics. - -3. **Social Interaction:** - 1. **Following & Followers:** - - [ ] Users can follow/unfollow other users. - - [ ] A timeline view displays posts from followed users. - - [ ] Users receive notifications for new followers. - 2. **Direct Messaging:** - - [ ] Private conversation threads between users. - - [ ] Option to block/unblock users from messaging. - 3. **Notifications:** - - [ ] Users are notified of likes, retweets, replies, and mentions. - -4. **Trending & Discovery:** - 1. **Trending Topics:** - - [ ] System identifies and displays trending hashtags or topics based on volume and velocity of mentions. - - [ ] Trending topics can be sorted based on location or globally. - 2. **User Recommendations:** - - [ ] Recommend users to follow based on interests, activity, and mutual followers. - -Once you've checked the code for each of the features and sub-features listed above, sum the total number of features that are implemented to get a numeric value. \ No newline at end of file diff --git a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/twitter/description_old.txt b/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/twitter/description_old.txt deleted file mode 100644 index 46974415..00000000 --- a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/twitter/description_old.txt +++ /dev/null @@ -1,49 +0,0 @@ -**Online Microblogging Service (OMS) - Description & Requirements** - -*Description:* -A web-based platform where registered users can post short text-based messages, view messages from others, follow/unfollow other users, and interact with posts. The platform provides features for both individual users and administrative management. - -**1. User Management:** -1.1. **Registration & Authentication:** -- Allow users to register using email, username, and password. -- Option to reset forgotten passwords. -- Secure authentication using JWT or similar protocols. - -1.2. **Profile Management:** -- Users can edit their profile information: profile picture, bio, website link, and location. -- Option to make profile private or public. - -**2. Posting & Content Management:** -2.1. **Creating Posts (Tweets):** -- Allow users to create text-based posts with a limit of 280 characters. -- Option to include images posts. -- Users can delete their own posts. - -2.2. **Interacting with Posts:** -- Users can like, retweet, and reply to posts. -- Nested comment structure for post replies. - -2.3. **Content Filtering & Search:** -- Users can search for specific posts or users using keywords. -- Filter option based on hashtags, user mentions, or trending topics. - -**3. Social Interaction:** -3.1. **Following & Followers:** -- Users can follow/unfollow other users. -- A timeline view displays posts from followed users. -- Users receive notifications for new followers. - -3.2. **Direct Messaging:** -- Private conversation threads between users. -- Option to block/unblock users from messaging. - -3.3. **Notifications:** -- Users are notified of likes, retweets, replies, and mentions. - -**4. Trending & Discovery:** -4.1. **Trending Topics:** -- System identifies and displays trending hashtags or topics based on volume and velocity of mentions. -- Trending topics can be sorted based on location or globally. - -4.2. **User Recommendations:** -- Recommend users to follow based on interests, activity, and mutual followers. diff --git a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/twitter/description_previous.txt b/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/twitter/description_previous.txt deleted file mode 100644 index 2864e00b..00000000 --- a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/twitter/description_previous.txt +++ /dev/null @@ -1,8 +0,0 @@ -Write complete MVC code for the following system design task. Design Twitter. -Features to implement: -1. Privacy controls around each tweet. -2. Users should be able to post tweets also the system should support replies to tweets/grouping tweets by conversations. -3. Users should be able to see trending tweets/posts. -4. Direct messaging -5. Mentions/Tagging. -6. The user should be able to follow another user. \ No newline at end of file diff --git a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/twitter/test_all.py b/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/twitter/test_all.py deleted file mode 100644 index e69de29b..00000000 diff --git a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/twitter/unit_tests_train.py b/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/twitter/unit_tests_train.py deleted file mode 100644 index 91d3f747..00000000 --- a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/twitter/unit_tests_train.py +++ /dev/null @@ -1,98 +0,0 @@ -import random -import string - -from my_oms import authenticate_user, register_user - - -def random_string(length=10): - """Generates a random string of specified length.""" - return "".join(random.choice(string.ascii_letters) for _ in range(length)) - - -def test_user_registration(): - username = random_string() - email = f"{random_string()}@example.com" - password = random_string() - - assert register_user(username, email, password) == True - - -def test_user_authentication(): - username = random_string() - email = f"{random_string()}@example.com" - password = random_string() - - register_user(username, email, password) - assert authenticate_user(email, password) == True - - -def test_profile_editing(): - user_id = random.randint(1, 1000) - new_bio = random_string(50) - new_website = f"https://{random_string()}.com" - new_location = random_string(15) - - assert edit_profile(user_id, new_bio, new_website, new_location) == True - - -def test_create_post(): - user_id = random.randint(1, 1000) - post_content = random_string(280) - - assert create_post(user_id, post_content) == True - - -def test_delete_post(): - user_id = random.randint(1, 1000) - post_id = create_post(user_id, random_string(280)) - - assert delete_post(user_id, post_id) == True - - -def test_post_interaction(): - user_id = random.randint(1, 1000) - post_id = create_post(random.randint(1, 1000), random_string(280)) - - assert like_post(user_id, post_id) == True - assert retweet_post(user_id, post_id) == True - assert reply_to_post(user_id, post_id, random_string(280)) == True - - -def test_post_search(): - keyword = random_string() - assert search_posts(keyword) is not None - - -def test_user_search(): - username = random_string() - assert search_users(username) is not None - - -def test_follow_unfollow(): - user_id = random.randint(1, 1000) - target_user_id = random.randint(1, 1000) - - assert follow_user(user_id, target_user_id) == True - assert unfollow_user(user_id, target_user_id) == True - - -def test_direct_messaging(): - sender_id = random.randint(1, 1000) - receiver_id = random.randint(1, 1000) - message = random_string(100) - - assert send_message(sender_id, receiver_id, message) == True - - -def test_notifications(): - user_id = random.randint(1, 1000) - assert get_notifications(user_id) is not None - - -def test_trending_topics(): - assert get_trending_topics() is not None - - -def test_user_recommendations(): - user_id = random.randint(1, 1000) - assert get_user_recommendations(user_id) is not None diff --git a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/url_shortener/description.txt b/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/url_shortener/description.txt deleted file mode 100644 index 4d33ea44..00000000 --- a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/url_shortener/description.txt +++ /dev/null @@ -1,35 +0,0 @@ -### **Online URL Shortening Service** - -**Overview**: -A service that allows users to submit long URLs and then receive a shortened version of that URL for ease of sharing. - -**Functional Requirements to implement**: - -1. **URL Shortening**: - - [ ] 1.1. Users can input a URL to be shortened. - - [ ] 1.2. The system validates that the URL is active and legitimate. - - [ ] 1.3. The system generates a unique shortened URL. - - [ ] 1.4. Users can choose custom short links (subject to availability). - -2. **Redirection**: - - [ ] 2.1. Accessing the shortened URL redirects to the original URL. - -3. **Analytics**: - - [ ] 3.1. Users can view statistics about their shortened URLs. - - [ ] 3.2. View number of clicks. - - [ ] 3.3. View date/time of each click. - - [ ] 3.4. View geographical location of the clicker. - -4. **User Accounts**: - - [ ] 4.1. Users can create accounts. - - [ ] 4.2. Account holders can view all their shortened URLs. - - [ ] 4.3. Account holders can edit or delete their shortened URLs. - - [ ] 4.4. Account holders can view analytics for all their shortened URLs. - -5. **Admin Dashboard**: - - [ ] 5.1. Administrators can view all shortened URLs. - - [ ] 5.2. Administrators can delete any URL or user account. - - [ ] 5.3. Administrators can monitor system performance and analytics. - -6. **Expiration**: - - [ ] 6.1. Users can set an expiration date/time for the shortened URL. \ No newline at end of file diff --git a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/url_shortener/description_count.txt b/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/url_shortener/description_count.txt deleted file mode 100644 index 5504b6e1..00000000 --- a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/url_shortener/description_count.txt +++ /dev/null @@ -1,38 +0,0 @@ -To evaluate the provided code based on the requirements for the "Online URL Shortening Service", you can use the following numbered checklist. For each feature present in the code, you can increment a numeric value: - -``` -**Evaluation Checklist for Online URL Shortening Service**: - -1. **URL Shortening**: - - [ ] 1.1. Users can input a URL to be shortened. - - [ ] 1.2. The system validates that the URL is active and legitimate. - - [ ] 1.3. The system generates a unique shortened URL. - - [ ] 1.4. Users can choose custom short links (subject to availability). - -2. **Redirection**: - - [ ] 2.1. Accessing the shortened URL redirects to the original URL. - -3. **Analytics**: - - [ ] 3.1. Users can view statistics about their shortened URLs. - - [ ] 3.2. View number of clicks. - - [ ] 3.3. View date/time of each click. - - [ ] 3.4. View geographical location of the clicker. - -4. **User Accounts**: - - [ ] 4.1. Users can create accounts. - - [ ] 4.2. Account holders can view all their shortened URLs. - - [ ] 4.3. Account holders can edit or delete their shortened URLs. - - [ ] 4.4. Account holders can view analytics for all their shortened URLs. - -5. **Admin Dashboard**: - - [ ] 5.1. Administrators can view all shortened URLs. - - [ ] 5.2. Administrators can delete any URL or user account. - - [ ] 5.3. Administrators can monitor system performance and analytics. - -6. **Expiration**: - - [ ] 6.1. Users can set an expiration date/time for the shortened URL. - -**Total Implemented Features**: [Count the checked boxes to get the numeric value] -``` - -You can go through the provided code and check off each item that has been implemented. At the end, count the checked boxes to get the numeric value for the number of features implemented. \ No newline at end of file diff --git a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/url_shortener/description_old.txt b/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/url_shortener/description_old.txt deleted file mode 100644 index e6c76f79..00000000 --- a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/url_shortener/description_old.txt +++ /dev/null @@ -1,35 +0,0 @@ -### **Online URL Shortening Service** - -**Overview**: -A service that allows users to submit long URLs and then receive a shortened version of that URL for ease of sharing. - -**Functional Requirements**: - -1. **URL Shortening**: - - Users can input a URL to be shortened. - - The system should validate that the URL is active and legitimate. - - The system should generate a unique shortened URL. - - Users can choose custom short links (subject to availability). - -2. **Redirection**: - - When users or their audience access the shortened URL, they should be redirected to the original URL. - -3. **Analytics**: - - Users can view statistics about their shortened URLs, including: - - Number of clicks. - - Date/time of each click. - - Geographical location of the clicker. - -4. **User Accounts**: - - Users can create accounts to manage their URLs. - - Account holders can view all their shortened URLs. - - Account holders can edit or delete their shortened URLs. - - Account holders can view analytics for all their shortened URLs. - -5. **Admin Dashboard**: - - Administrators can view all shortened URLs. - - Administrators can delete any URL or user account. - - Administrators can monitor system performance and analytics. - -6. **Expiration**: - - Allow users to set an expiration date/time for the shortened URL after which it becomes inactive. diff --git a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/url_shortener/description_previous.txt b/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/url_shortener/description_previous.txt deleted file mode 100644 index 56c213c9..00000000 --- a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/url_shortener/description_previous.txt +++ /dev/null @@ -1,7 +0,0 @@ -Write complete MVC code for the following system design task. Design a URL Shortening Service (TinyURL) -Features to implement: -1. Given a long URL, the service should generate a shorter and unique alias for it. -2. When the user hits a short link, the service should redirect to the original link. -3. Support for custom short URLs. -4. Track click stats. -5. Delete expired URLs. \ No newline at end of file diff --git a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/url_shortener/test_all.py b/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/url_shortener/test_all.py deleted file mode 100644 index e69de29b..00000000 diff --git a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/url_shortener/unit_tests_test.py b/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/url_shortener/unit_tests_test.py deleted file mode 100644 index e69de29b..00000000 diff --git a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/url_shortener/unit_tests_train.py b/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/url_shortener/unit_tests_train.py deleted file mode 100644 index 76e90add..00000000 --- a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/url_shortener/unit_tests_train.py +++ /dev/null @@ -1,87 +0,0 @@ -import string -from datetime import datetime, timedelta -from random import choices, randint - - -# Helper Functions -def random_url(): - return f"https://example{randint(1000, 9999)}.com" - - -def random_username(): - return "user" + "".join(choices(string.ascii_lowercase + string.digits, k=5)) - - -def random_slug(): - return "".join(choices(string.ascii_lowercase + string.digits, k=8)) - - -# Test Functions -class TestURLShorteningService: - def test_input_url_shortening(self): - url = random_url() - shortened_url = shorten_url(url) - assert isinstance(shortened_url, str) - assert len(shortened_url) < len(url) - - def test_url_validation(self): - valid_url = random_url() - invalid_url = "htp:/invalid" + "".join(choices(string.ascii_lowercase + string.digits, k=10)) - assert validate_url(valid_url) is True - assert validate_url(invalid_url) is False - - def test_unique_shortened_url(self): - url = random_url() - shortened_url1 = shorten_url(url) - shortened_url2 = shorten_url(url) - assert shortened_url1 != shortened_url2 - - def test_custom_short_link(self): - url = random_url() - custom_slug = random_slug() - custom_short_url = shorten_url(url, custom_slug) - assert custom_slug in custom_short_url - - def test_redirection(self): - original_url = random_url() - shortened_url = shorten_url(original_url) - redirected_url = redirect(shortened_url) - assert redirected_url == original_url - - def test_analytics_retrieval(self): - shortened_url = shorten_url(random_url()) - analytics = get_analytics(shortened_url) - assert "clicks" in analytics - assert "click_dates" in analytics - assert "click_geolocations" in analytics - - def test_user_account_functions(self): - username = random_username() - user = create_user(username, "password") - assert user is not None - urls = user.get_shortened_urls() - assert isinstance(urls, list) - user.edit_url("old_short_url", "new_short_url") - assert "new_short_url" in user.get_shortened_urls() - user.delete_url("new_short_url") - assert "new_short_url" not in user.get_shortened_urls() - analytics = user.get_analytics("short_url") - assert analytics is not None - - def test_admin_functions(self): - admin = create_admin("admin_username", "admin_password") - all_urls = admin.get_all_urls() - assert isinstance(all_urls, list) - admin.delete_url("some_short_url") - assert "some_short_url" not in admin.get_all_urls() - admin.delete_user("username") - assert admin.get_user("username") is None - system_stats = admin.get_system_stats() - assert system_stats is not None - - def test_url_expiration(self): - url = random_url() - expiration_time = datetime.now() + timedelta(minutes=randint(1, 60)) - shortened_url = shorten_url(url, expiration_time=expiration_time) - assert check_expiration(shortened_url) is False - # Additional code to simulate waiting until after expiration may be required diff --git a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/whatsapp/description.txt b/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/whatsapp/description.txt deleted file mode 100644 index 365a9aec..00000000 --- a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/whatsapp/description.txt +++ /dev/null @@ -1,41 +0,0 @@ -**Global Chat Service (GCS)** - -**Overview**: -A real-time online chat application allowing users to send text messages, images, and create group chats. - -**Functional Requirements to implement**: - -User Registration and Authentication: -- [ ] 1.1. Sign up using email. -- [ ] 1.2. Forgotten password recovery. - -User Profile: -- [ ] 2.1. Allow users to set profile pictures and status messages. -- [ ] 2.2. Privacy settings for who can see user details or last seen status. - -Contact Management: -- [ ] 3.1. Block/unblock contacts. -- [ ] 3.2. Create, edit, and manage groups. - -Messaging: -- [ ] 4.1. Send and receive real-time text messages. -- [ ] 4.2. Message read receipts (blue ticks or equivalent). -- [ ] 4.3. End-to-end encryption for security. -- [ ] 4.4. Image sharing. -- [ ] 4.5. Emojis, GIFs, and stickers support. - -Group Chats: -- [ ] 5.1. Create group chats with a name and picture. -- [ ] 5.2. Add or remove participants. -- [ ] 5.3. Admin roles and permissions. - -Status/Story Feature: -- [ ] 6.1. Allow users to post image statuses visible for a limited time. -- [ ] 6.2. Control who can see the status. - -Web Application: -- [ ] 7.1. Web-based version accessible from browsers. - -Connectivity and Offline Mode: -- [ ] 8.1. Message queuing for when the user is offline; messages are sent once connectivity is restored. -- [ ] 8.2. Display online/offline status. \ No newline at end of file diff --git a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/whatsapp/description_count.txt b/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/whatsapp/description_count.txt deleted file mode 100644 index aa083d7f..00000000 --- a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/whatsapp/description_count.txt +++ /dev/null @@ -1,40 +0,0 @@ -To evaluate a given code against the listed features, follow this numbered list. For each feature implemented in the code, add one to your count. - -Global Chat Service (GCS) Evaluation Checklist: - -User Registration and Authentication: -- [ ] 1.1. Sign up using email. -- [ ] 1.2. Forgotten password recovery. - -User Profile: -- [ ] 2.1. Allow users to set profile pictures and status messages. -- [ ] 2.2. Privacy settings for who can see user details or last seen status. - -Contact Management: -- [ ] 3.1. Block/unblock contacts. -- [ ] 3.2. Create, edit, and manage groups. - -Messaging: -- [ ] 4.1. Send and receive real-time text messages. -- [ ] 4.2. Message read receipts (blue ticks or equivalent). -- [ ] 4.3. End-to-end encryption for security. -- [ ] 4.4. Image sharing. -- [ ] 4.5. Emojis, GIFs, and stickers support. - -Group Chats: -- [ ] 5.1. Create group chats with a name and picture. -- [ ] 5.2. Add or remove participants. -- [ ] 5.3. Admin roles and permissions. - -Status/Story Feature: -- [ ] 6.1. Allow users to post image statuses visible for a limited time. -- [ ] 6.2. Control who can see the status. - -Web Application: -- [ ] 7.1. Web-based version accessible from browsers. - -Connectivity and Offline Mode: -- [ ] 8.1. Message queuing for when the user is offline; messages are sent once connectivity is restored. -- [ ] 8.2. Display online/offline status. - -Once you've checked the code for each of the features and sub-features listed above, sum the total number of features that are implemented to get a numeric value. \ No newline at end of file diff --git a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/whatsapp/description_old.txt b/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/whatsapp/description_old.txt deleted file mode 100644 index 9bd3c5ba..00000000 --- a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/whatsapp/description_old.txt +++ /dev/null @@ -1,41 +0,0 @@ -**Global Chat Service (GCS)** - -**Overview**: -A real-time online chat application allowing users to send text messages, images, and create group chats. - -**Functional Requirements**: - -1. **User Registration and Authentication**: - - Sign up using email. - - Forgotten password recovery. - -2. **User Profile**: - - Allow users to set profile pictures and status messages. - - Privacy settings for who can see user details or last seen status. - -3. **Contact Management**: - - Block/unblock contacts. - - Create, edit, and manage groups. - -4. **Messaging**: - - Send and receive real-time text messages. - - Message read receipts (blue ticks or equivalent). - - End-to-end encryption for security. - - Image sharing. - - Emojis, GIFs, and stickers support. - -5. **Group Chats**: - - Create group chats with a name and picture. - - Add or remove participants. - - Admin roles and permissions. - -6. **Status/Story Feature**: - - Allow users to post image statuses visible for a limited time. - - Control who can see the status. - -7. **Web Application**: - - Web-based version accessible from browsers. - -8. **Connectivity and Offline Mode**: - - Message queuing for when the user is offline; messages are sent once connectivity is restored. - - Display online/offline status. \ No newline at end of file diff --git a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/whatsapp/description_previous.txt b/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/whatsapp/description_previous.txt deleted file mode 100644 index 06c122e2..00000000 --- a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/whatsapp/description_previous.txt +++ /dev/null @@ -1,7 +0,0 @@ -Write complete MVC code for the following system design task. Design Facebook Messenger or WhatsApp (A Global Chat Service) -Features to implement: -1. One-on-one text messaging between users. -2. Support group chats. -3. Delivered and read status -4. Support sending .jpg images between users. -5. End-to-end message encryption. \ No newline at end of file diff --git a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/whatsapp/test_all.py b/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/whatsapp/test_all.py deleted file mode 100644 index d183171a..00000000 --- a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/whatsapp/test_all.py +++ /dev/null @@ -1 +0,0 @@ -# Empty diff --git a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/whatsapp/unit_tests_train.py b/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/whatsapp/unit_tests_train.py deleted file mode 100644 index c939eee2..00000000 --- a/examples/experiments/data/donnemartin-system-design-oop/object_oriented_design/whatsapp/unit_tests_train.py +++ /dev/null @@ -1,139 +0,0 @@ -import random -import string - - -def test_signup_with_email(auth_service): - email = f"{''.join(random.choices(string.ascii_letters, k=5))}@example.com" - password = "Test@1234" - assert auth_service.sign_up(email, password) == True - - -def test_forgotten_password_recovery(auth_service, user_emails): - email = random.choice(user_emails) - assert auth_service.recover_password(email) == True - - -def test_set_profile_picture_and_status(user_service): - user_id = random.randint(1, 100) - picture_path = f"/path/to/picture{random.randint(1, 5)}.jpg" - status_message = f"Status {random.randint(1, 100)}" - assert user_service.set_profile(user_id, picture_path, status_message) == True - - -def test_privacy_settings(user_service): - user_id = random.randint(1, 100) - privacy_settings = random.choice(["Everyone", "Contacts", "Nobody"]) - assert user_service.set_privacy(user_id, privacy_settings) == True - - -def test_block_unblock_contact(contact_service, user_id, contacts_list): - contact_id = random.choice(contacts_list) - assert contact_service.block_contact(user_id, contact_id) == True - assert contact_service.unblock_contact(user_id, contact_id) == True - - -def test_manage_group(group_service): - user_id = random.randint(1, 100) - group_name = f"Group {random.randint(1, 100)}" - group_id = group_service.create_group(user_id, group_name) - assert group_id is not None - - new_group_name = f"Group {random.randint(101, 200)}" - assert group_service.edit_group(user_id, group_id, new_group_name) == True - - -def test_send_receive_messages(message_service): - sender_id = random.randint(1, 100) - receiver_id = random.randint(1, 100) - message = f"Hello! {random.randint(1, 1000)}" - assert message_service.send_message(sender_id, receiver_id, message) == True - assert message_service.receive_message(receiver_id) == message - - -def test_read_receipts(message_service): - sender_id = random.randint(1, 100) - receiver_id = random.randint(1, 100) - message_id = message_service.send_message(sender_id, receiver_id, "Test message") - assert message_service.mark_as_read(receiver_id, message_id) == True - - -def test_end_to_end_encryption(message_service): - sender_id = random.randint(1, 100) - receiver_id = random.randint(1, 100) - message = f"Secret {random.randint(1, 1000)}" - encrypted_message = message_service.encrypt_message(sender_id, message) - assert encrypted_message != message - sent_message_id = message_service.send_message(sender_id, receiver_id, encrypted_message) - received_encrypted_message = message_service.receive_message(receiver_id, sent_message_id) - decrypted_message = message_service.decrypt_message(receiver_id, received_encrypted_message) - assert decrypted_message == message - - -def test_image_sharing(message_service): - sender_id = random.randint(1, 100) - receiver_id = random.randint(1, 100) - image_path = f"/path/to/image{random.randint(1, 5)}.jpg" - assert message_service.send_image(sender_id, receiver_id, image_path) == True - assert message_service.receive_image(receiver_id) == image_path - - -def test_emojis_gifs_stickers(message_service): - sender_id = random.randint(1, 100) - receiver_id = random.randint(1, 100) - content = random.choice(["Emoji 😀", "GIF [gif_file_path]", "Sticker [sticker_file_path]"]) - assert message_service.send_content(sender_id, receiver_id, content) == True - assert message_service.receive_content(receiver_id) == content - - -def test_create_group_chat(group_chat_service): - user_id = random.randint(1, 100) - group_name = f"Group Chat {random.randint(1, 100)}" - group_picture = f"/path/to/group_picture{random.randint(1, 5)}.jpg" - assert group_chat_service.create_group(user_id, group_name, group_picture) is not None - - -def test_add_remove_participants(group_chat_service, group_id, user_ids): - participant_to_add = random.choice(user_ids) - participant_to_remove = random.choice(user_ids) - assert group_chat_service.add_participant(group_id, participant_to_add) == True - assert group_chat_service.remove_participant(group_id, participant_to_remove) == True - - -def test_admin_roles_permissions(group_chat_service, group_id, user_id): - assert group_chat_service.assign_admin(group_id, user_id) == True - new_permissions = random.choice(["Add members", "Remove members", "Edit group info"]) - assert group_chat_service.change_admin_permissions(group_id, user_id, new_permissions) == True - - -def test_post_image_status(status_service): - user_id = random.randint(1, 100) - image_status = f"/path/to/status_image{random.randint(1, 5)}.jpg" - duration = random.randint(1, 24) # Hours - assert status_service.post_image_status(user_id, image_status, duration) == True - - -def test_status_visibility(status_service, user_id): - visibility_settings = random.choice(["Everyone", "Contacts", "Nobody"]) - assert status_service.set_status_visibility(user_id, visibility_settings) == True - - -def test_web_application_access(web_app_service): - user_id = random.randint(1, 100) - assert web_app_service.access_web_version(user_id) == True - - -def test_message_queuing(offline_service): - sender_id = random.randint(1, 100) - receiver_id = random.randint(1, 100) - offline_service.set_offline(sender_id) - message = f"Message {random.randint(1, 1000)}" - assert offline_service.send_message(sender_id, receiver_id, message) == "Queued" - offline_service.set_online(sender_id) - assert offline_service.check_message_sent(sender_id, receiver_id) == True - - -def test_online_offline_status(user_status_service): - user_id = random.randint(1, 100) - status = random.choice(["online", "offline"]) - user_status_service.set_status(user_id, status) - assert user_status_service.get_status(user_id) == status diff --git a/examples/generate_codebase_simple_blackjack.py b/examples/generate_codebase_simple_blackjack.py index 2aab6bdc..e35dc134 100644 --- a/examples/generate_codebase_simple_blackjack.py +++ b/examples/generate_codebase_simple_blackjack.py @@ -1,5 +1,6 @@ from l2mac import generate_codebase +# run pip install pygame==2.1.2 (for best results) codebase: dict = generate_codebase("Create a simple playable blackjack cli game", steps=2, run_tests=True) print(codebase) # it will print the codebase (repo) complete with all the files as a dictionary diff --git a/examples/generate_codebase_simple_playable_snake.py b/examples/generate_codebase_simple_playable_snake.py index 9e1bd2ab..e84b2778 100644 --- a/examples/generate_codebase_simple_playable_snake.py +++ b/examples/generate_codebase_simple_playable_snake.py @@ -1,5 +1,6 @@ from l2mac import generate_codebase +# run pip install pygame==2.1.2 codebase: dict = generate_codebase( "Create a beautiful, playable and simple snake game with pygame. Make the snake and food be aligned to the same 10-pixel grid.", steps=2, diff --git a/requirements.txt b/requirements.txt index 4f40c580..87d62347 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,41 +4,4 @@ typer>=0.9.0 numpy openai tiktoken -timeout-decorator - - - - -# ALl -# wandb -# pygame==2.1.2 -# pycryptodome -# Flask-Migrate -# scipy -# pandas -# tqdm -# flask -# flask_sqlalchemy -# flask_migrate -# flask_login -# flask_wtf -# flask_bcrypt -# flask_mail -# flask_admin -# flask_bootstrap -# flask_moment -# flask_uploads -# flask_dropzone -# flask_simplemde -# flask_script -# pygount -# radon -# matplotlib -# pytest -# pylint -# Werkzeug==2.0.1 -# Pillow==8.2.0 -# itsdangerous -# pytest-flask -# email-validator -# PyJWT \ No newline at end of file +timeout-decorator \ No newline at end of file diff --git a/setup.py b/setup.py index d611ffea..9f8f68e0 100644 --- a/setup.py +++ b/setup.py @@ -20,7 +20,6 @@ packages=find_packages(exclude=["contrib", "docs", "examples", "tests*"]), include_package_data=True, package_data={ - # If any package contains *.yaml files, include them: "": ["*.yaml"], }, python_requires=">=3.9", diff --git a/tests/test_function_calling.py b/tests/test_function_calling.py deleted file mode 100644 index 58440f0f..00000000 --- a/tests/test_function_calling.py +++ /dev/null @@ -1,91 +0,0 @@ -import json - -from openai import OpenAI - -from l2mac.config import load_config - -config = load_config() -client = OpenAI(api_key=config.llm.api_key) - - -# Example dummy function hard coded to return the same weather -# In production, this could be your backend API or an external API -def get_current_weather(location, unit="fahrenheit"): - """Get the current weather in a given location""" - if "tokyo" in location.lower(): - return json.dumps({"location": "Tokyo", "temperature": "10", "unit": unit}) - elif "san francisco" in location.lower(): - return json.dumps({"location": "San Francisco", "temperature": "72", "unit": unit}) - elif "paris" in location.lower(): - return json.dumps({"location": "Paris", "temperature": "22", "unit": unit}) - else: - return json.dumps({"location": location, "temperature": "unknown"}) - - -def run_conversation(): - # Step 1: send the conversation and available functions to the model - messages = [{"role": "user", "content": "What's the weather like in San Francisco, Tokyo, and Paris?"}] - tools = [ - { - "type": "function", - "function": { - "name": "get_current_weather", - "description": "Get the current weather in a given location", - "parameters": { - "type": "object", - "properties": { - "location": { - "type": "string", - "description": "The city and state, e.g. San Francisco, CA", - }, - "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}, - }, - "required": ["location"], - }, - }, - } - ] - response = client.chat.completions.create( - model=config.llm.model, - messages=messages, - tools=tools, - tool_choice="auto", # auto is default, but we'll be explicit - ) - response_message = response.choices[0].message - tool_calls = response_message.tool_calls - # Step 2: check if the model wanted to call a function - if tool_calls: - # Step 3: call the function - # Note: the JSON response may not always be valid; be sure to handle errors - available_functions = { - "get_current_weather": get_current_weather, - } # only one function in this example, but you can have multiple - response_message = json.loads(response_message.model_dump_json()) - response_message = {k: v for k, v in response_message.items() if v is not None} - messages.append(response_message) # extend conversation with assistant's reply - # Step 4: send the info for each function call and function response to the model - for tool_call in tool_calls: - function_name = tool_call.function.name - function_to_call = available_functions[function_name] - function_args = json.loads(tool_call.function.arguments) - function_response = function_to_call( - location=function_args.get("location"), - unit=function_args.get("unit"), - ) - messages.append( - { - "tool_call_id": tool_call.id, - "role": "tool", - "name": function_name, - "content": function_response, - } - ) # extend conversation with function response - second_response = client.chat.completions.create( - model="gpt-3.5-turbo-0125", - messages=messages, - ) # get a new response from the model where it can see the function response - return second_response - - -print(run_conversation()) -print("") diff --git a/tests/test_l2mac.py b/tests/test_l2mac.py index e69de29b..cf1848bd 100644 --- a/tests/test_l2mac.py +++ b/tests/test_l2mac.py @@ -0,0 +1,2 @@ +def test_l2mac(): + assert True