[
  {
    "path": ".coveragerc",
    "content": "[run]\r\nrelative_files = true"
  },
  {
    "path": ".devcontainer/Dockerfile",
    "content": "# Use an official Python base image from the Docker Hub\nFROM python:3.10\n\n# Install browsers\nRUN apt-get update && apt-get install -y \\\n    chromium-driver firefox-esr \\\n    ca-certificates\n\n# Install utilities\nRUN apt-get install -y curl jq wget git\n\n# Declare working directory\nWORKDIR /workspace/Auto-GPT\n"
  },
  {
    "path": ".devcontainer/devcontainer.json",
    "content": "{\n  \"dockerComposeFile\": \"./docker-compose.yml\",\n  \"service\": \"auto-gpt\",\n  \"workspaceFolder\": \"/workspace/Auto-GPT\",\n  \"shutdownAction\": \"stopCompose\",\n  \"features\": {\n    \"ghcr.io/devcontainers/features/common-utils:2\": {\n      \"installZsh\": \"true\",\n      \"username\": \"vscode\",\n      \"userUid\": \"6942\",\n      \"userGid\": \"6942\",\n      \"upgradePackages\": \"true\"\n    },\n    \"ghcr.io/devcontainers/features/desktop-lite:1\": {},\n    \"ghcr.io/devcontainers/features/python:1\": \"none\",\n    \"ghcr.io/devcontainers/features/node:1\": \"none\",\n    \"ghcr.io/devcontainers/features/git:1\": {\n      \"version\": \"latest\",\n      \"ppa\": \"false\"\n    }\n  },\n  // Configure tool-specific properties.\n  \"customizations\": {\n    // Configure properties specific to VS Code.\n    \"vscode\": {\n      // Set *default* container specific settings.json values on container create.\n      \"settings\": {\n        \"python.defaultInterpreterPath\": \"/usr/local/bin/python\"\n      }\n    }\n  },\n  // Use 'forwardPorts' to make a list of ports inside the container available locally.\n  // \"forwardPorts\": [],\n\n  // Use 'postCreateCommand' to run commands after the container is created.\n  // \"postCreateCommand\": \"pip3 install --user -r requirements.txt\",\n\n  // Set `remoteUser` to `root` to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.\n  \"remoteUser\": \"vscode\"\n}\n"
  },
  {
    "path": ".devcontainer/docker-compose.yml",
    "content": "# To boot the app run the following:\n# docker-compose run auto-gpt\nversion: '3.9'\n\nservices:\n  auto-gpt:\n    depends_on:\n      - redis\n    build:\n      dockerfile: .devcontainer/Dockerfile\n      context: ../\n    tty: true\n    environment:\n      MEMORY_BACKEND: ${MEMORY_BACKEND:-redis}\n      REDIS_HOST: ${REDIS_HOST:-redis}\n    volumes:\n      - ../:/workspace/Auto-GPT\n  redis:\n    image: 'redis/redis-stack-server:latest'\n"
  },
  {
    "path": ".dockerignore",
    "content": ".*\n*.template\n*.yaml\n*.yml\n\n*.md\n*.png\n!BULLETIN.md\n"
  },
  {
    "path": ".envrc",
    "content": "# Upon entering directory, direnv requests user permission once to automatically load project dependencies onwards.\n# Eliminating the need of running \"nix develop github:superherointj/nix-auto-gpt\" for Nix users to develop/use Auto-GPT.\n\n[[ -z $IN_NIX_SHELL ]] && use flake github:superherointj/nix-auto-gpt\n"
  },
  {
    "path": ".flake8",
    "content": "[flake8]\nmax-line-length = 88\nselect = \"E303, W293, W291, W292, E305, E231, E302\"\nexclude =\n    .tox,\n    __pycache__,\n    *.pyc,\n    .env\n    venv*/*,\n    .venv/*,\n    reports/*,\n    dist/*,\n"
  },
  {
    "path": ".gitattributes",
    "content": "# Exclude VCR cassettes from stats\ntests/**/cassettes/**.y*ml linguist-generated\n\n# Mark documentation as such\ndocs/**.md linguist-documentation\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "# These are supported funding model platforms\n\ngithub: Torantulino\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/1.bug.yml",
    "content": "name: Bug report 🐛\ndescription: Create a bug report for Auto-GPT.\nlabels: ['status: needs triage']\nbody:\n  - type: markdown\n    attributes:\n      value: |\n        ### ⚠️ Before you continue\n        * Check out our [backlog], [roadmap] and join our [discord] to discuss what's going on\n        * If you need help, you can ask in the [discussions] section or in [#tech-support]\n        * **Throughly search the [existing issues] before creating a new one**\n        * Read our [wiki page on Contributing]\n\n        [backlog]: https://github.com/orgs/Significant-Gravitas/projects/1\n        [roadmap]: https://github.com/orgs/Significant-Gravitas/projects/2  \n        [discord]: https://discord.gg/autogpt\n        [discussions]: https://github.com/Significant-Gravitas/Auto-GPT/discussions\n        [#tech-support]: https://discord.com/channels/1092243196446249134/1092275629602394184\n        [existing issues]: https://github.com/Significant-Gravitas/Auto-GPT/issues?q=is%3Aissue\n        [wiki page on Contributing]: https://github.com/Significant-Gravitas/Auto-GPT/wiki/Contributing\n  - type: checkboxes\n    attributes:\n      label: ⚠️ Search for existing issues first ⚠️\n      description: >\n        Please [search the history](https://github.com/Torantulino/Auto-GPT/issues)\n        to see if an issue already exists for the same problem.\n      options:\n        - label: I have searched the existing issues, and there is no existing issue for my problem\n          required: true\n  - type: markdown\n    attributes:\n      value: |\n        Please provide a searchable summary of the issue in the title above ⬆️.\n\n        ⚠️ SUPER-busy repo, please help the volunteer maintainers.\n        The less time we spend here, the more time we spend building AutoGPT.\n        \n        Please help us help you:\n        - Does it work on `stable` branch (https://github.com/Torantulino/Auto-GPT/tree/stable)?\n        - Does it work on current `master` (https://github.com/Torantulino/Auto-GPT/tree/master)?\n        - Search for existing issues, \"add comment\" is tidier than \"new issue\"\n        - Ask on our Discord (https://discord.gg/autogpt)\n        - Provide relevant info:\n          - Provide commit-hash (`git rev-parse HEAD` gets it)\n          - If it's a pip/packages issue, provide pip version, python version\n          - If it's a crash, provide traceback.\n  - type: dropdown\n    attributes:\n      label: Which Operating System are you using?\n      description: >\n        Please select the operating system you were using to run Auto-GPT when this problem occurred.\n      options:\n        - Windows\n        - Linux\n        - MacOS\n        - Docker\n        - Devcontainer / Codespace\n        - Windows Subsystem for Linux (WSL)\n        - Other (Please specify in your problem)\n    validations:\n      required: true\n  - type: dropdown\n    attributes:\n      label: Which version of Auto-GPT are you using?\n      description: |\n        Please select which version of Auto-GPT you were using when this issue occurred.\n        If you downloaded the code from the [releases page](https://github.com/Significant-Gravitas/Auto-GPT/releases/) make sure you were using the latest code. \n        **If you weren't please try with the [latest code](https://github.com/Significant-Gravitas/Auto-GPT/releases/)**.\n        If installed with git you can run `git branch` to see which version of Auto-GPT you are running.\n      options:\n        - Latest Release\n        - Stable (branch)\n        - Master (branch)\n    validations:\n      required: true\n  - type: dropdown\n    attributes:\n      label: GPT-3 or GPT-4?\n      description: >\n        If you are using Auto-GPT with `--gpt3only`, your problems may be caused by\n        the [limitations](https://github.com/Significant-Gravitas/Auto-GPT/issues?q=is%3Aissue+label%3A%22AI+model+limitation%22) of GPT-3.5.\n      options:\n        - GPT-3.5\n        - GPT-4\n    validations:\n      required: true\n  - type: textarea\n    attributes:\n      label: Steps to reproduce 🕹\n      description: |\n        **⚠️ Issues that we can't reproduce will be closed.**\n  - type: textarea\n    attributes:\n      label: Current behavior 😯\n      description: Describe what happens instead of the expected behavior.\n  - type: textarea\n    attributes:\n      label: Expected behavior 🤔\n      description: Describe what should happen.\n  - type: textarea\n    attributes:\n      label: Your prompt 📝\n      description: >\n        If applicable please provide the prompt you are using. Your prompt is stored in your `ai_settings.yaml` file.\n      value: |\n        ```yaml\n        # Paste your prompt here\n        ```\n  - type: textarea\n    attributes:\n      label: Your Logs 📒\n      description: |\n        Please include the log showing your error and the command that caused it, if applicable.\n        You can copy it from your terminal or from `logs/activity.log`.\n        This will help us understand your issue better!\n        \n        <details>\n        <summary><i>Example</i></summary>\n        ```log\n        INFO NEXT ACTION:  COMMAND = execute_shell  ARGUMENTS = {'command_line': 'some_command'}\n        INFO -=-=-=-=-=-=-= COMMAND AUTHORISED BY USER -=-=-=-=-=-=-=\n        Traceback (most recent call last):\n        File \"/home/anaconda3/lib/python3.9/site-packages/openai/api_requestor.py\", line 619, in _interpret_response\n        self._interpret_response_line(\n        File \"/home/anaconda3/lib/python3.9/site-packages/openai/api_requestor.py\", line 682, in _interpret_response_line\n        raise self.handle_error_response(\n        openai.error.InvalidRequestError: This model's maximum context length is 8191 tokens, however you requested 10982 tokens (10982 in your prompt; 0 for the completion). Please reduce your prompt; or completion length.\n        ```\n        </details>\n      value: |\n        ```log\n        <insert your logs here>\n        ```\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/2.feature.yml",
    "content": "name: Feature request 🚀\ndescription: Suggest a new idea for Auto-GPT!\nlabels: ['status: needs triage']\nbody:\n  - type: markdown\n    attributes:\n      value: |\n        First, check out our [wiki page on Contributing](https://github.com/Significant-Gravitas/Auto-GPT/wiki/Contributing)\n        Please provide a searchable summary of the issue in the title above ⬆️.\n  - type: checkboxes\n    attributes:\n      label: Duplicates\n      description: Please [search the history](https://github.com/Torantulino/Auto-GPT/issues) to see if an issue already exists for the same problem.\n      options:\n        - label: I have searched the existing issues\n          required: true\n  - type: textarea\n    attributes:\n      label: Summary 💡\n      description: Describe how it should work.\n  - type: textarea\n    attributes:\n      label: Examples 🌈\n      description: Provide a link to other implementations, or screenshots of the expected behavior.\n  - type: textarea\n    attributes:\n      label: Motivation 🔦\n      description: What are you trying to accomplish? How has the lack of this feature affected you? Providing context helps us come up with a solution that is more useful in the real world.\n"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "content": "<!-- ⚠️ At the moment any non-essential commands are not being merged.\nIf you want to add non-essential commands to Auto-GPT, please create a plugin instead.\nWe are expecting to ship plugin support within the week (PR #757).\nResources:\n* https://github.com/Significant-Gravitas/Auto-GPT-Plugin-Template\n-->\n\n<!-- 📢 Announcement\nWe've recently noticed an increase in pull requests focusing on combining multiple changes. While the intentions behind these PRs are appreciated, it's essential to maintain a clean and manageable git history. To ensure the quality of our repository, we kindly ask you to adhere to the following guidelines when submitting PRs:\n\nFocus on a single, specific change.\nDo not include any unrelated or \"extra\" modifications.\nProvide clear documentation and explanations of the changes made.\nEnsure diffs are limited to the intended lines — no applying preferred formatting styles or line endings (unless that's what the PR is about).\nFor guidance on committing only the specific lines you have changed, refer to this helpful video: https://youtu.be/8-hSNHHbiZg\n\nCheck out our [wiki page on Contributing](https://github.com/Significant-Gravitas/Auto-GPT/wiki/Contributing)\n\nBy following these guidelines, your PRs are more likely to be merged quickly after testing, as long as they align with the project's overall direction. -->\n\n### Background\n<!-- Provide a concise overview of the rationale behind this change. Include relevant context, prior discussions, or links to related issues. Ensure that the change aligns with the project's overall direction. -->\n\n### Changes\n<!-- Describe the specific, focused change made in this pull request. Detail the modifications clearly and avoid any unrelated or \"extra\" changes. -->\n\n### Documentation\n<!-- Explain how your changes are documented, such as in-code comments or external documentation. Ensure that the documentation is clear, concise, and easy to understand. -->\n\n### Test Plan\n<!-- Describe how you tested this functionality. Include steps to reproduce, relevant test cases, and any other pertinent information. -->\n\n### PR Quality Checklist\n- [ ] My pull request is atomic and focuses on a single change.\n- [ ] I have thoroughly tested my changes with multiple different prompts.\n- [ ] I have considered potential risks and mitigations for my changes.\n- [ ] I have documented my changes clearly and comprehensively.\n- [ ] I have not snuck in any \"extra\" small tweaks changes <!-- Submit these as separate Pull Requests, they are the easiest to merge! -->\n\n<!-- If you haven't added tests, please explain why. If you have, check the appropriate box. If you've ensured your PR is atomic and well-documented, check the corresponding boxes. -->\n\n<!-- By submitting this, I agree that my pull request should be closed if I do not fill this out or follow the guidelines. -->\n"
  },
  {
    "path": ".github/workflows/benchmarks.yml",
    "content": "name: Run Benchmarks\n\non:\n  workflow_dispatch:\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n\n    env:\n      python-version: '3.10'\n\n    steps:\n    - name: Checkout repository\n      uses: actions/checkout@v3\n\n    - name: Set up Python ${{ env.python-version }}\n      uses: actions/setup-python@v4\n      with:\n        python-version: ${{ env.python-version }}\n\n    - name: Install dependencies\n      run: |\n        python -m pip install --upgrade pip\n        pip install -r requirements.txt\n\n    - name: benchmark\n      env:\n        OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}\n      run: |\n         python benchmark/benchmark_entrepreneur_gpt_with_undecisive_user.py\n"
  },
  {
    "path": ".github/workflows/ci.yml",
    "content": "name: Python CI\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    branches: [ master, stable ]\n\nconcurrency:\n  group: ${{ format('ci-{0}', github.head_ref && format('pr-{0}', github.event.pull_request.number) || github.sha) }}\n  cancel-in-progress: ${{ github.event_name == 'pull_request' }}\n\njobs:\n  lint:\n    runs-on: ubuntu-latest\n    env:\n      min-python-version: \"3.10\"\n\n    steps:\n      - name: Checkout repository\n        uses: actions/checkout@v3\n\n      - name: Set up Python ${{ env.min-python-version }}\n        uses: actions/setup-python@v2\n        with:\n          python-version: ${{ env.min-python-version }}\n\n      - name: Install dependencies\n        run: |\n          python -m pip install --upgrade pip\n          pip install -r requirements.txt\n\n      - name: Lint with flake8\n        run: flake8\n\n      - name: Check black formatting\n        run: black . --check\n        if: success() || failure()\n\n      - name: Check isort formatting\n        run: isort . --check\n        if: success() || failure()\n\n  test:\n    permissions:\n      # Gives the action the necessary permissions for publishing new\n      # comments in pull requests.\n      pull-requests: write\n      # Gives the action the necessary permissions for pushing data to the\n      # python-coverage-comment-action branch, and for editing existing\n      # comments (to avoid publishing multiple comments in the same PR)\n      contents: write\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n        python-version: [\"3.10\", \"3.11\"]\n\n    steps:\n      - name: Check out repository\n        uses: actions/checkout@v3\n\n      - name: Set up Python ${{ matrix.python-version }}\n        uses: actions/setup-python@v2\n        with:\n          python-version: ${{ matrix.python-version }}\n\n      - name: Install dependencies\n        run: |\n          python -m pip install --upgrade pip\n          pip install -r requirements.txt\n\n      - name: Run unittest tests with coverage\n        run: |\n          pytest --cov=autogpt --cov-report term-missing --cov-branch --cov-report xml --cov-report term\n        env:\n          CI: true\n\n      - name: Upload coverage reports to Codecov\n        uses: codecov/codecov-action@v3\n"
  },
  {
    "path": ".github/workflows/docker-cache-clean.yml",
    "content": "name: Purge Docker CI cache\n\non:\n  schedule:\n    - cron: 20 4 * * 1,4\n\nenv:\n  BASE_BRANCH: master\n  IMAGE_NAME: auto-gpt\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n        build-type: [release, dev]\n    steps:\n    - name: Checkout repository\n      uses: actions/checkout@v3\n\n    - name: Set up Docker Buildx\n      uses: docker/setup-buildx-action@v2\n\n    - id: build\n      name: Build image\n      uses: docker/build-push-action@v3\n      with:\n        build-args: BUILD_TYPE=${{ matrix.build-type }}\n        load: true    # save to docker images\n        # use GHA cache as read-only\n        cache-to: type=gha,scope=docker-${{ matrix.build-type }},mode=max\n\n    - name: Generate build report\n      env:\n        event_name: ${{ github.event_name }}\n        event_ref: ${{ github.event.schedule }}\n\n        build_type: ${{ matrix.build-type }}\n\n        prod_branch: stable\n        dev_branch: master\n        repository: ${{ github.repository }}\n        base_branch: ${{ github.ref_name != 'master' && github.ref_name != 'stable' && 'master' || 'stable' }}\n\n        current_ref: ${{ github.ref_name }}\n        commit_hash: ${{ github.sha }}\n        source_url: ${{ format('{0}/tree/{1}', github.event.repository.url, github.sha) }}\n        push_forced_label:\n\n        new_commits_json: ${{ null }}\n        compare_url_template: ${{ format('/{0}/compare/{{base}}...{{head}}', github.repository) }}\n\n        github_context_json: ${{ toJSON(github) }}\n        job_env_json: ${{ toJSON(env) }}\n        vars_json: ${{ toJSON(vars) }}\n\n      run: .github/workflows/scripts/docker-ci-summary.sh >> $GITHUB_STEP_SUMMARY\n      continue-on-error: true\n"
  },
  {
    "path": ".github/workflows/docker-ci.yml",
    "content": "name: Docker CI\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    branches: [ master, stable ]\n\nconcurrency:\n  group: ${{ format('docker-ci-{0}', github.head_ref && format('pr-{0}', github.event.pull_request.number) || github.sha) }}\n  cancel-in-progress: ${{ github.event_name == 'pull_request' }}\n\nenv:\n  IMAGE_NAME: auto-gpt\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n        build-type: [release, dev]\n    steps:\n    - name: Checkout repository\n      uses: actions/checkout@v3\n\n    - name: Set up Docker Buildx\n      uses: docker/setup-buildx-action@v2\n\n    - if: runner.debug\n      run: |\n        ls -al\n        du -hs *\n\n    - id: build\n      name: Build image\n      uses: docker/build-push-action@v3\n      with:\n        build-args: BUILD_TYPE=${{ matrix.build-type }}\n        tags: ${{ env.IMAGE_NAME }}\n        load: true    # save to docker images\n        # cache layers in GitHub Actions cache to speed up builds\n        cache-from: type=gha,scope=docker-${{ matrix.build-type }}\n        cache-to: type=gha,scope=docker-${{ matrix.build-type }},mode=max\n\n    - name: Generate build report\n      env:\n        event_name: ${{ github.event_name }}\n        event_ref: ${{ github.event.ref }}\n        event_ref_type: ${{ github.event.ref}}\n\n        build_type: ${{ matrix.build-type }}\n\n        prod_branch: stable\n        dev_branch: master\n        repository: ${{ github.repository }}\n        base_branch: ${{ github.ref_name != 'master' && github.ref_name != 'stable' && 'master' || 'stable' }}\n\n        current_ref: ${{ github.ref_name }}\n        commit_hash: ${{ github.event.after }}\n        source_url: ${{ format('{0}/tree/{1}', github.event.repository.url, github.event.release && github.event.release.tag_name || github.sha) }}\n        push_forced_label: ${{ github.event.forced && '☢️ forced' || '' }}\n\n        new_commits_json: ${{ toJSON(github.event.commits) }}\n        compare_url_template: ${{ format('/{0}/compare/{{base}}...{{head}}', github.repository) }}\n\n        github_context_json: ${{ toJSON(github) }}\n        job_env_json: ${{ toJSON(env) }}\n        vars_json: ${{ toJSON(vars) }}\n\n      run: .github/workflows/scripts/docker-ci-summary.sh >> $GITHUB_STEP_SUMMARY\n      continue-on-error: true\n\n  # Docker setup needs fixing before this is going to work: #1843\n  test:\n    runs-on: ubuntu-latest\n    needs: build\n    steps:\n    - name: Checkout repository\n      uses: actions/checkout@v3\n\n    - name: Set up Docker Buildx\n      uses: docker/setup-buildx-action@v2\n\n    - id: build\n      name: Build image\n      uses: docker/build-push-action@v3\n      with:\n        build-args: BUILD_TYPE=dev  # include pytest\n        tags: ${{ env.IMAGE_NAME }}\n        load: true                  # save to docker images\n        # cache layers in GitHub Actions cache to speed up builds\n        cache-from: type=gha,scope=docker-dev\n        cache-to: type=gha,scope=docker-dev,mode=max\n\n    - id: test\n      name: Run tests\n      env:\n        CI: true\n        OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}\n      run: |\n        set +e\n        test_output=$(\n          docker run --env CI --env OPENAI_API_KEY --entrypoint python ${{ env.IMAGE_NAME }} -m \\\n          pytest --cov=autogpt --cov-report term-missing --cov-branch --cov-report xml --cov-report term 2>&1\n        )\n        test_failure=$?\n\n        echo \"$test_output\"\n\n        cat << $EOF >> $GITHUB_STEP_SUMMARY\n        # Tests $([ $test_failure = 0 ] && echo '✅' || echo '❌')\n        \\`\\`\\`\n        $test_output\n        \\`\\`\\`\n        $EOF\n"
  },
  {
    "path": ".github/workflows/docker-release.yml",
    "content": "name: Docker Release\n\non:\n  release:\n    types: [ published, edited ]\n\n  workflow_dispatch:\n    inputs:\n      no_cache:\n        type: boolean\n        description: 'Build from scratch, without using cached layers'\n\nenv:\n  IMAGE_NAME: auto-gpt\n  DEPLOY_IMAGE_NAME: ${{ secrets.DOCKER_USER }}/auto-gpt\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n    - name: Checkout repository\n      uses: actions/checkout@v3\n\n    - name: Log in to Docker hub\n      uses: docker/login-action@v2\n      with:\n        username: ${{ secrets.DOCKER_USER }}\n        password: ${{ secrets.DOCKER_PASSWORD }}\n\n    - name: Set up Docker Buildx\n      uses: docker/setup-buildx-action@v2\n\n      # slashes are not allowed in image tags, but can appear in git branch or tag names\n    - id: sanitize_tag\n      name: Sanitize image tag\n      run: echo tag=${raw_tag//\\//-} >> $GITHUB_OUTPUT\n      env:\n        raw_tag: ${{ github.ref_name }}\n\n    - id: build\n      name: Build image\n      uses: docker/build-push-action@v3\n      with:\n        build-args: BUILD_TYPE=release\n        load: true    # save to docker images\n        # push: true  # TODO: uncomment when this issue is fixed: https://github.com/moby/buildkit/issues/1555\n        tags: >\n          ${{ env.IMAGE_NAME }},\n          ${{ env.DEPLOY_IMAGE_NAME }}:latest,\n          ${{ env.DEPLOY_IMAGE_NAME }}:${{ steps.sanitize_tag.outputs.tag }}\n\n        # cache layers in GitHub Actions cache to speed up builds\n        cache-from: ${{ !inputs.no_cache && 'type=gha' || '' }},scope=docker-release\n        cache-to: type=gha,scope=docker-release,mode=max\n\n    - name: Push image to Docker Hub\n      run: docker push --all-tags ${{ env.DEPLOY_IMAGE_NAME }}\n\n    - name: Generate build report\n      env:\n        event_name: ${{ github.event_name }}\n        event_ref: ${{ github.event.ref }}\n        event_ref_type: ${{ github.event.ref}}\n        inputs_no_cache: ${{ inputs.no_cache }}\n\n        prod_branch: stable\n        dev_branch: master\n        repository: ${{ github.repository }}\n        base_branch: ${{ github.ref_name != 'master' && github.ref_name != 'stable' && 'master' || 'stable' }}\n\n        ref_type: ${{ github.ref_type }}\n        current_ref: ${{ github.ref_name }}\n        commit_hash: ${{ github.sha }}\n        source_url: ${{ format('{0}/tree/{1}', github.event.repository.url, github.event.release && github.event.release.tag_name || github.sha) }}\n\n        github_context_json: ${{ toJSON(github) }}\n        job_env_json: ${{ toJSON(env) }}\n        vars_json: ${{ toJSON(vars) }}\n\n      run: .github/workflows/scripts/docker-release-summary.sh >> $GITHUB_STEP_SUMMARY\n      continue-on-error: true\n"
  },
  {
    "path": ".github/workflows/documentation-release.yml",
    "content": "name: Docs\n\non:\n  push:\n    branches: [ stable ]\n    paths:\n      - 'docs/**'\n      - 'mkdocs.yml'\n      - '.github/workflows/documentation.yml'\n\n  # Allows you to run this workflow manually from the Actions tab\n  workflow_dispatch:\n\npermissions:\n  contents: write\n\njobs:\n  deploy:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout repository\n        uses: actions/checkout@v3\n\n      - name: Set up Python 3\n        uses: actions/setup-python@v4\n        with:\n          python-version: 3.x\n\n      - name: Set up workflow cache\n        uses: actions/cache@v3\n        with:\n          key: ${{ github.ref }}\n          path: .cache\n\n      - run: pip install mkdocs-material\n\n      - run: mkdocs gh-deploy --force\n"
  },
  {
    "path": ".github/workflows/pr-label.yml",
    "content": "name: \"Pull Request auto-label\"\n\non:\n  # So that PRs touching the same files as the push are updated\n  push:\n    branches: [ master ]\n  # So that the `dirtyLabel` is removed if conflicts are resolve\n  # We recommend `pull_request_target` so that github secrets are available.\n  # In `pull_request` we wouldn't be able to change labels of fork PRs\n  pull_request_target:\n    types: [ opened, synchronize ]\n\nconcurrency:\n  group: ${{ format('pr-label-{0}', github.event.pull_request.number || github.sha) }}\n  cancel-in-progress: true\n\njobs:\n  conflicts:\n    runs-on: ubuntu-latest\n    permissions:\n      contents: read\n      pull-requests: write\n    steps:\n      - name: Update PRs with conflict labels\n        uses: eps1lon/actions-label-merge-conflict@releases/2.x\n        with:\n          dirtyLabel: \"conflicts\"\n          #removeOnDirtyLabel: \"PR: ready to ship\"\n          repoToken: \"${{ secrets.GITHUB_TOKEN }}\"\n          commentOnDirty: \"This pull request has conflicts with the base branch, please resolve those so we can evaluate the pull request.\"\n          commentOnClean: \"Conflicts have been resolved! 🎉 A maintainer will review the pull request shortly.\"\n\n  size:\n    if: ${{ github.event_name == 'pull_request_target' }}\n    permissions:\n      issues: write\n      pull-requests: write\n    runs-on: ubuntu-latest\n    steps:\n      - uses: codelytv/pr-size-labeler@v1\n        with:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n          xs_label: 'size/xs'\n          xs_max_size: 2\n          s_label: 'size/s'\n          s_max_size: 10\n          m_label: 'size/m'\n          m_max_size: 50\n          l_label: 'size/l'\n          l_max_size: 200\n          xl_label: 'size/xl'\n          message_if_xl: >\n            This PR exceeds the recommended size of 200 lines.\n            Please make sure you are NOT addressing multiple issues with one PR.\n            Note this PR might be rejected due to its size  \n"
  },
  {
    "path": ".github/workflows/scripts/docker-ci-summary.sh",
    "content": "#!/bin/bash\nmeta=$(docker image inspect \"$IMAGE_NAME\" | jq '.[0]')\nhead_compare_url=$(sed \"s/{base}/$base_branch/; s/{head}/$current_ref/\" <<< $compare_url_template)\nref_compare_url=$(sed \"s/{base}/$base_branch/; s/{head}/$commit_hash/\" <<< $compare_url_template)\n\nEOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)\n\ncat << $EOF\n# Docker Build summary 🔨\n\n**Source:** branch \\`$current_ref\\` -> [$repository@\\`${commit_hash:0:7}\\`]($source_url)\n\n**Build type:** \\`$build_type\\`\n\n**Image size:** $((`jq -r .Size <<< $meta` / 10**6))MB\n\n## Image details\n\n**Tags:**\n$(jq -r '.RepoTags | map(\"* `\\(.)`\") | join(\"\\n\")' <<< $meta)\n\n<details>\n<summary><h3>Layers</h3></summary>\n\n|    Age    |  Size  | Created by instruction |\n| --------- | ------ | ---------------------- |\n$(docker history --no-trunc --format \"{{.CreatedSince}}\\t{{.Size}}\\t\\`{{.CreatedBy}}\\`\\t{{.Comment}}\" $IMAGE_NAME \\\n    | grep 'buildkit.dockerfile' `# filter for layers created in this build process`\\\n    | cut -f-3                   `# yeet Comment column`\\\n    | sed 's/ ago//'             `# fix Layer age`\\\n    | sed 's/ # buildkit//'      `# remove buildkit comment from instructions`\\\n    | sed 's/\\$/\\\\$/g'           `# escape variable and shell expansions`\\\n    | sed 's/|/\\\\|/g'            `# escape pipes so they don't interfere with column separators`\\\n    | column -t -s$'\\t' -o' | '  `# align columns and add separator`\\\n    | sed 's/^/| /; s/$/ |/'     `# add table row start and end pipes`)\n</details>\n\n<details>\n<summary><h3>ENV</h3></summary>\n\n| Variable | Value    |\n| -------- | -------- |\n$(jq -r \\\n    '.Config.Env\n    | map(\n    split(\"=\")\n    | \"\\(.[0]) | `\\(.[1] | gsub(\"\\\\s+\"; \" \"))`\"\n    )\n    | map(\"| \\(.) |\")\n    | .[]' <<< $meta\n)\n</details>\n\n<details>\n<summary>Raw metadata</summary>\n\n\\`\\`\\`JSON\n$meta\n\\`\\`\\`\n</details>\n\n## Build details\n**Build trigger:** $push_forced_label $event_name \\`$event_ref\\`\n\n<details>\n<summary><code>github</code> context</summary>\n\n\\`\\`\\`JSON\n$github_context_json\n\\`\\`\\`\n</details>\n\n### Source\n**HEAD:** [$repository@\\`${commit_hash:0:7}\\`]($source_url) on branch [$current_ref]($ref_compare_url)\n\n**Diff with previous HEAD:** $head_compare_url\n\n#### New commits\n$(jq -r 'map([\n    \"**Commit [`\\(.id[0:7])`](\\(.url)) by \\(if .author.username then \"@\"+.author.username else .author.name end):**\",\n    .message,\n    (if .committer.name != .author.name then \"\\n> <sub>**Committer:** \\(.committer.name) <\\(.committer.email)></sub>\" else \"\" end),\n    \"<sub>**Timestamp:** \\(.timestamp)</sub>\"\n] | map(\"> \\(.)\\n\") | join(\"\")) | join(\"\\n\")' <<< $new_commits_json)\n\n### Job environment\n\n#### \\`vars\\` context:\n\\`\\`\\`JSON\n$vars_json\n\\`\\`\\`\n\n#### \\`env\\` context:\n\\`\\`\\`JSON\n$job_env_json\n\\`\\`\\`\n\n$EOF\n"
  },
  {
    "path": ".github/workflows/scripts/docker-release-summary.sh",
    "content": "#!/bin/bash\nmeta=$(docker image inspect \"$IMAGE_NAME\" | jq '.[0]')\n\nEOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)\n\ncat << $EOF\n# Docker Release Build summary 🚀🔨\n\n**Source:** $ref_type \\`$current_ref\\` -> [$repository@\\`${commit_hash:0:7}\\`]($source_url)\n\n**Image size:** $((`jq -r .Size <<< $meta` / 10**6))MB\n\n## Image details\n\n**Tags:**\n$(jq -r '.RepoTags | map(\"* `\\(.)`\") | join(\"\\n\")' <<< $meta)\n\n<details>\n<summary><h3>Layers</h3></summary>\n\n|    Age    |  Size  | Created by instruction |\n| --------- | ------ | ---------------------- |\n$(docker history --no-trunc --format \"{{.CreatedSince}}\\t{{.Size}}\\t\\`{{.CreatedBy}}\\`\\t{{.Comment}}\" $IMAGE_NAME \\\n    | grep 'buildkit.dockerfile' `# filter for layers created in this build process`\\\n    | cut -f-3                   `# yeet Comment column`\\\n    | sed 's/ ago//'             `# fix Layer age`\\\n    | sed 's/ # buildkit//'      `# remove buildkit comment from instructions`\\\n    | sed 's/\\$/\\\\$/g'           `# escape variable and shell expansions`\\\n    | sed 's/|/\\\\|/g'            `# escape pipes so they don't interfere with column separators`\\\n    | column -t -s$'\\t' -o' | '  `# align columns and add separator`\\\n    | sed 's/^/| /; s/$/ |/'     `# add table row start and end pipes`)\n</details>\n\n<details>\n<summary><h3>ENV</h3></summary>\n\n| Variable | Value    |\n| -------- | -------- |\n$(jq -r \\\n    '.Config.Env\n    | map(\n    split(\"=\")\n    | \"\\(.[0]) | `\\(.[1] | gsub(\"\\\\s+\"; \" \"))`\"\n    )\n    | map(\"| \\(.) |\")\n    | .[]' <<< $meta\n)\n</details>\n\n<details>\n<summary>Raw metadata</summary>\n\n\\`\\`\\`JSON\n$meta\n\\`\\`\\`\n</details>\n\n## Build details\n**Build trigger:** $event_name \\`$current_ref\\`\n\n| Parameter      | Value        |\n| -------------- | ------------ |\n| \\`no_cache\\`   | \\`$inputs_no_cache\\` |\n\n<details>\n<summary><code>github</code> context</summary>\n\n\\`\\`\\`JSON\n$github_context_json\n\\`\\`\\`\n</details>\n\n### Job environment\n\n#### \\`vars\\` context:\n\\`\\`\\`JSON\n$vars_json\n\\`\\`\\`\n\n#### \\`env\\` context:\n\\`\\`\\`JSON\n$job_env_json\n\\`\\`\\`\n\n$EOF\n"
  },
  {
    "path": ".github/workflows/sponsors_readme.yml",
    "content": "name: Generate Sponsors README\n\non:\n  workflow_dispatch:\n  schedule:\n    - cron: '0 */12 * * *'\n\njobs:\n  deploy:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout 🛎️\n        uses: actions/checkout@v3\n\n      - name: Generate Sponsors 💖\n        uses: JamesIves/github-sponsors-readme-action@v1\n        with:\n          token: ${{ secrets.README_UPDATER_PAT }}\n          file: 'README.md'\n          minimum: 2500\n          maximum: 99999\n\n      - name: Deploy to GitHub Pages 🚀\n        uses: JamesIves/github-pages-deploy-action@v4\n        with:\n          branch: master\n          folder: '.'\n          token: ${{ secrets.README_UPDATER_PAT }}\n"
  },
  {
    "path": ".gitignore",
    "content": "## Original ignores\nautogpt/keys.py\nautogpt/*json\nautogpt/node_modules/\nautogpt/__pycache__/keys.cpython-310.pyc\nautogpt/auto_gpt_workspace\npackage-lock.json\n*.pyc\nauto_gpt_workspace/*\n*.mpeg\n.env\nazure.yaml\nai_settings.yaml\nlast_run_ai_settings.yaml\n.vscode\n.idea/*\nauto-gpt.json\nlog.txt\nlog-ingestion.txt\nlogs\n*.log\n*.mp3\nmem.sqlite3\n\n# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n*$py.class\n\n# C extensions\n*.so\n\n# Distribution / packaging\n.Python\nbuild/\ndevelop-eggs/\ndist/\nplugins/\ndownloads/\neggs/\n.eggs/\nlib/\nlib64/\nparts/\nsdist/\nvar/\nwheels/\npip-wheel-metadata/\nshare/python-wheels/\n*.egg-info/\n.installed.cfg\n*.egg\nMANIFEST\n\n# PyInstaller\n#  Usually these files are written by a python script from a template\n#  before PyInstaller builds the exe, so as to inject date/other infos into it.\n*.manifest\n*.spec\n\n# Installer logs\npip-log.txt\npip-delete-this-directory.txt\n\n# Unit test / coverage reports\nhtmlcov/\n.tox/\n.nox/\n.coverage\n.coverage.*\n.cache\nnosetests.xml\ncoverage.xml\n*.cover\n*.py,cover\n.hypothesis/\n.pytest_cache/\n\n# Translations\n*.mo\n*.pot\n\n# Django stuff:\n*.log\nlocal_settings.py\ndb.sqlite3\ndb.sqlite3-journal\n\n# Flask stuff:\ninstance/\n.webassets-cache\n\n# Scrapy stuff:\n.scrapy\n\n# Sphinx documentation\ndocs/_build/\nsite/\n\n# PyBuilder\ntarget/\n\n# Jupyter Notebook\n.ipynb_checkpoints\n\n# IPython\nprofile_default/\nipython_config.py\n\n# pyenv\n.python-version\n\n# pipenv\n#   According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.\n#   However, in case of collaboration, if having platform-specific dependencies or dependencies\n#   having no cross-platform support, pipenv may install dependencies that don't work, or not\n#   install all needed dependencies.\n#Pipfile.lock\n\n# PEP 582; used by e.g. github.com/David-OConnor/pyflow\n__pypackages__/\n\n# Celery stuff\ncelerybeat-schedule\ncelerybeat.pid\n\n# SageMath parsed files\n*.sage.py\n\n# Environments\n.direnv/\n.env\n.venv\nenv/\nvenv*/\nENV/\nenv.bak/\n\n# Spyder project settings\n.spyderproject\n.spyproject\n\n# Rope project settings\n.ropeproject\n\n# mkdocs documentation\n/site\n\n# mypy\n.mypy_cache/\n.dmypy.json\ndmypy.json\n\n# Pyre type checker\n.pyre/\nllama-*\nvicuna-*\n\n# mac\n.DS_Store\n\nopenai/\n\n# news\nCURRENT_BULLETIN.md"
  },
  {
    "path": ".isort.cfg",
    "content": "[settings]\nprofile = black\nmulti_line_output = 3\ninclude_trailing_comma = true\nforce_grid_wrap = 0\nuse_parentheses = true\nensure_newline_before_comments = true\nline_length = 88\nsections = FUTURE,STDLIB,THIRDPARTY,FIRSTPARTY,LOCALFOLDER\nskip = .tox,__pycache__,*.pyc,venv*/*,reports,venv,env,node_modules,.env,.venv,dist\n"
  },
  {
    "path": ".pre-commit-config.yaml",
    "content": "repos:\n  - repo: https://github.com/pre-commit/pre-commit-hooks\n    rev: v4.4.0\n    hooks:\n      - id: check-added-large-files\n        args: ['--maxkb=500']\n      - id: check-byte-order-marker\n      - id: check-case-conflict\n      - id: check-merge-conflict\n      - id: check-symlinks\n      - id: debug-statements\n\n  - repo: https://github.com/pycqa/isort\n    rev: 5.12.0\n    hooks:\n      - id: isort\n        language_version: python3.10\n\n  - repo: https://github.com/psf/black\n    rev: 23.3.0\n    hooks:\n      - id: black\n        language_version: python3.10\n\n  - repo: local\n    hooks:\n      - id: pytest-check\n        name: pytest-check\n        entry: pytest --cov=autogpt --without-integration --without-slow-integration\n        language: system\n        pass_filenames: false\n        always_run: true\n"
  },
  {
    "path": ".sourcery.yaml",
    "content": "# 🪄 This is your project's Sourcery configuration file.\n\n# You can use it to get Sourcery working in the way you want, such as\n# ignoring specific refactorings, skipping directories in your project,\n# or writing custom rules.\n\n# 📚 For a complete reference to this file, see the documentation at\n# https://docs.sourcery.ai/Configuration/Project-Settings/\n\n# This file was auto-generated by Sourcery on 2023-02-25 at 21:07.\n\nversion: '1'  # The schema version of this config file\n\nignore: # A list of paths or files which Sourcery will ignore.\n- .git\n- venv\n- .venv\n- build\n- dist\n- env\n- .env\n- .tox\n\nrule_settings:\n  enable:\n  - default\n  - gpsg\n  disable: []  # A list of rule IDs Sourcery will never suggest.\n  rule_types:\n  - refactoring\n  - suggestion\n  - comment\n  python_version: '3.10' # A string specifying the lowest Python version your project supports. Sourcery will not suggest refactorings requiring a higher Python version.\n\n# rules:  # A list of custom rules Sourcery will include in its analysis.\n# - id: no-print-statements\n#   description: Do not use print statements in the test directory.\n#   pattern: print(...)\n#   language: python\n#   replacement:\n#   condition:\n#   explanation:\n#   paths:\n#     include:\n#     - test\n#     exclude:\n#     - conftest.py\n#   tests: []\n#   tags: []\n\n# rule_tags: {} # Additional rule tags.\n\n# metrics:\n#   quality_threshold: 25.0\n\n# github:\n#   labels: []\n#   ignore_labels:\n#   - sourcery-ignore\n#   request_review: author\n#   sourcery_branch: sourcery/{base_branch}\n\n# clone_detection:\n#   min_lines: 3\n#   min_duplicates: 2\n#   identical_clones_only: false\n\n# proxy:\n#   url:\n#   ssl_certs_file:\n#   no_ssl_verify: false\n"
  },
  {
    "path": "BULLETIN.md",
    "content": "# 持续更新中\nAuto-GPT 0.3.0最大更新为自动定义AI名称，角色，任务等，也可以进入手动模式\n对插件（Plugin）的支持也在逐渐强大，可玩性更强\n我正在逐步修改汉化0.3.0稳定版本，如果你喜欢我的工作，请给我一个star，谢谢！关注我的频道www.youtube.com/@hossie\n\n\n# 官方网站与文档站 📰📖\n使用说明与最新信息 *https://agpt.co*\n相关文档 *https://docs.agpt.co*\n\n# 🚀 最新更新 🚀\n1. 基础命令汉化\n2. 将一些Prompt转化为中文更好理解内容\n3. 已完成部分插件汉化\n\n# 🚀 未来更新 🚀\n1. 简单的插件汉化\n2. 优化已有汉化内容\n3. 跟踪官方更新\n\n# ⚠️  `send_tweet` 已经被废弃, 0.4.0版本中将彻底删除 ⚠️\nTwitter 功能将通过Plugin完成 [Plugin support 🔌]\n"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "content": "# Code of Conduct for Auto-GPT\n\n## 1. Purpose\n\nThe purpose of this Code of Conduct is to provide guidelines for contributors to the auto-gpt project on GitHub. We aim to create a positive and inclusive environment where all participants can contribute and collaborate effectively. By participating in this project, you agree to abide by this Code of Conduct.\n\n## 2. Scope\n\nThis Code of Conduct applies to all contributors, maintainers, and users of the auto-gpt project. It extends to all project spaces, including but not limited to issues, pull requests, code reviews, comments, and other forms of communication within the project.\n\n## 3. Our Standards\n\nWe encourage the following behavior:\n\n* Being respectful and considerate to others\n* Actively seeking diverse perspectives\n* Providing constructive feedback and assistance\n* Demonstrating empathy and understanding\n\nWe discourage the following behavior:\n\n* Harassment or discrimination of any kind\n* Disrespectful, offensive, or inappropriate language or content\n* Personal attacks or insults\n* Unwarranted criticism or negativity\n\n## 4. Reporting and Enforcement\n\nIf you witness or experience any violations of this Code of Conduct, please report them to the project maintainers by email or other appropriate means. The maintainers will investigate and take appropriate action, which may include warnings, temporary or permanent bans, or other measures as necessary.\n\nMaintainers are responsible for ensuring compliance with this Code of Conduct and may take action to address any violations.\n\n## 5. Acknowledgements\n\nThis Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org/version/2/0/code_of_conduct.html).\n\n## 6. Contact\n\nIf you have any questions or concerns, please contact the project maintainers.\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "This document now lives at https://github.com/Significant-Gravitas/Auto-GPT/wiki/Contributing\n"
  },
  {
    "path": "Dockerfile",
    "content": "# 'dev' or 'release' container build\nARG BUILD_TYPE=dev\n\n# Use an official Python base image from the Docker Hub\nFROM python:3.10-slim AS autogpt-base\n\n# Install browsers\nRUN apt-get update && apt-get install -y \\\n    chromium-driver firefox-esr \\\n    ca-certificates\n\n# Install utilities\nRUN apt-get install -y curl jq wget git\n\n# Set environment variables\nENV PIP_NO_CACHE_DIR=yes \\\n    PYTHONUNBUFFERED=1 \\\n    PYTHONDONTWRITEBYTECODE=1\n\n# Install the required python packages globally\nENV PATH=\"$PATH:/root/.local/bin\"\nCOPY requirements.txt .\n\n# Set the entrypoint\nENTRYPOINT [\"python\", \"-m\", \"autogpt\"]\n\n# dev build -> include everything\nFROM autogpt-base as autogpt-dev\nRUN pip install --no-cache-dir -r requirements.txt\nWORKDIR /app\nONBUILD COPY . ./\n\n# release build -> include bare minimum\nFROM autogpt-base as autogpt-release\nRUN sed -i '/Items below this point will not be included in the Docker Image/,$d' requirements.txt && \\\n\tpip install --no-cache-dir -r requirements.txt\nWORKDIR /app\nONBUILD COPY autogpt/ ./autogpt\nONBUILD COPY scripts/ ./scripts\n\n\nFROM autogpt-${BUILD_TYPE} AS auto-gpt\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2023 Toran Bruce Richards\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# Auto-GPT中文版\n### Youtube频道：https://www.youtube.com/@Hossie\n##\n<hr/>\n\n\n<h2 align=\"center\"> 💖 大家好 💖</h2>\n\n<p align=\"center\">\n这个项目是基于Auto-GPT原作者的0.3.0Stable版本，应大家要求，我快速制作了中文的汉化版本，基本运行顺利，还有些小瑕疵，会不断更新修改，欢迎大家关注，还请大家多支持！下面的内容就不过多翻译了，保持与原作者一致！\n如果大家希望支持我，还请给我点个小星星，谢谢！也可以通过微信与我们交流\n\n<p align=\"center\">\n  <a href=\"https://raw.githubusercontent.com/RealHossie/Auto-GPT-Chinese/master/docs/imgs/wechat.png\">\n    <img src=\"https://raw.githubusercontent.com/RealHossie/Auto-GPT-Chinese/master/docs/imgs/wechat.png\" alt=\"微信\">\n  </a>\n</p>\n\n</div>\n\n</br>\n</br>\n\n<p align=\"center\">\n  <a href=\"https://star-history.com/#Realhossie/auto-gpt-chinese&Date\">\n    <img src=\"https://api.star-history.com/svg?repos=Realhossie/auto-gpt-chinese&type=Date\" alt=\"Star History Chart\">\n  </a>\n</p>\n\n## 🚀 Features\n\n- 🌐 Internet access for searches and information gathering\n- 💾 Long-term and short-term memory management\n- 🧠 GPT-4 instances for text generation\n- 🔗 Access to popular websites and platforms\n- 🗃️ File storage and summarization with GPT-3.5\n- 🔌 Extensibility with Plugins\n\n## Quickstart\n\n1. Get an OpenAI [API Key](https://platform.openai.com/account/api-keys)\n2. Download the [latest release](https://github.com/Significant-Gravitas/Auto-GPT/releases/latest)\n3. Follow the [installation instructions][docs/setup]\n4. Configure any additional features you want, or install some [plugins][docs/plugins]\n5. [Run][docs/usage] the app\n\nPlease see the [documentation][docs] for full setup instructions and configuration options.\n\n[docs]: https://docs.agpt.co/\n\n## 📖 Documentation\n* [⚙️ Setup][docs/setup]\n* [💻 Usage][docs/usage]\n* [🔌 Plugins][docs/plugins]\n* Configuration\n  * [🔍 Web Search](https://docs.agpt.co/configuration/search/)\n  * [🧠 Memory](https://docs.agpt.co/configuration/memory/)\n  * [🗣️ Voice (TTS)](https://docs.agpt.co/configuration/voice/)\n  * [🖼️ Image Generation](https://docs.agpt.co/configuration/imagegen/)\n\n[docs/setup]: https://docs.agpt.co/setup/\n[docs/usage]: https://docs.agpt.co/usage/\n[docs/plugins]: https://docs.agpt.co/plugins/"
  },
  {
    "path": "autogpt/__init__.py",
    "content": "import os\nimport random\nimport sys\n\nfrom dotenv import load_dotenv\n\nif \"pytest\" in sys.argv or \"pytest\" in sys.modules or os.getenv(\"CI\"):\n    print(\"Setting random seed to 42\")\n    random.seed(42)\n\n# Load the users .env file into environment variables\nload_dotenv(verbose=True, override=True)\n\ndel load_dotenv\n"
  },
  {
    "path": "autogpt/__main__.py",
    "content": "\"\"\"Auto-GPT: A GPT powered AI Assistant\"\"\"\nimport autogpt.cli\n\nif __name__ == \"__main__\":\n    autogpt.cli.main()\n"
  },
  {
    "path": "autogpt/agent/__init__.py",
    "content": "from autogpt.agent.agent import Agent\nfrom autogpt.agent.agent_manager import AgentManager\n\n__all__ = [\"Agent\", \"AgentManager\"]\n"
  },
  {
    "path": "autogpt/agent/agent.py",
    "content": "from colorama import Fore, Style\n\nfrom autogpt.app import execute_command, get_command\nfrom autogpt.config import Config\nfrom autogpt.json_utils.json_fix_llm import fix_json_using_multiple_techniques\nfrom autogpt.json_utils.utilities import LLM_DEFAULT_RESPONSE_FORMAT, validate_json\nfrom autogpt.llm import chat_with_ai, create_chat_completion, create_chat_message\nfrom autogpt.llm.token_counter import count_string_tokens\nfrom autogpt.logs import logger, print_assistant_thoughts\nfrom autogpt.speech import say_text\nfrom autogpt.spinner import Spinner\nfrom autogpt.utils import clean_input\nfrom autogpt.workspace import Workspace\n\n\nclass Agent:\n    \"\"\"Agent class for interacting with Auto-GPT.\n\n    Attributes:\n        ai_name: The name of the agent.\n        memory: The memory object to use.\n        full_message_history: The full message history.\n        next_action_count: The number of actions to execute.\n        system_prompt: The system prompt is the initial prompt that defines everything\n          the AI needs to know to achieve its task successfully.\n        Currently, the dynamic and customizable information in the system prompt are\n          ai_name, description and goals.\n\n        triggering_prompt: The last sentence the AI will see before answering.\n            For Auto-GPT, this prompt is:\n            Determine which next command to use, and respond using the format specified\n              above:\n            The triggering prompt is not part of the system prompt because between the\n              system prompt and the triggering\n            prompt we have contextual information that can distract the AI and make it\n              forget that its goal is to find the next task to achieve.\n            SYSTEM PROMPT\n            CONTEXTUAL INFORMATION (memory, previous conversations, anything relevant)\n            TRIGGERING PROMPT\n\n        The triggering prompt reminds the AI about its short term meta task\n        (defining the next task)\n    \"\"\"\n\n    def __init__(\n        self,\n        ai_name,\n        memory,\n        full_message_history,\n        next_action_count,\n        command_registry,\n        config,\n        system_prompt,\n        triggering_prompt,\n        workspace_directory,\n    ):\n        cfg = Config()\n        self.ai_name = ai_name\n        self.memory = memory\n        self.summary_memory = (\n            \"我被生成完毕.\"  # Initial memory necessary to avoid hilucination\n        )\n        self.last_memory_index = 0\n        self.full_message_history = full_message_history\n        self.next_action_count = next_action_count\n        self.command_registry = command_registry\n        self.config = config\n        self.system_prompt = system_prompt\n        self.triggering_prompt = triggering_prompt\n        self.workspace = Workspace(workspace_directory, cfg.restrict_to_workspace)\n\n    def start_interaction_loop(self):\n        # Interaction Loop\n        cfg = Config()\n        loop_count = 0\n        command_name = None\n        arguments = None\n        user_input = \"\"\n\n        while True:\n            # Discontinue if continuous limit is reached\n            loop_count += 1\n            if (\n                cfg.continuous_mode\n                and cfg.continuous_limit > 0\n                and loop_count > cfg.continuous_limit\n            ):\n                logger.typewriter_log(\n                    \"持续模式次数已到达: \", Fore.YELLOW, f\"{cfg.continuous_limit}\"\n                )\n                break\n            # Send message to AI, get response\n            with Spinner(\"琢磨中... \"):\n                assistant_reply = chat_with_ai(\n                    self,\n                    self.system_prompt,\n                    self.triggering_prompt,\n                    self.full_message_history,\n                    self.memory,\n                    cfg.fast_token_limit,\n                )  # TODO: This hardcodes the model to use GPT3.5. Make this an argument\n\n            assistant_reply_json = fix_json_using_multiple_techniques(assistant_reply)\n            for plugin in cfg.plugins:\n                if not plugin.can_handle_post_planning():\n                    continue\n                assistant_reply_json = plugin.post_planning(self, assistant_reply_json)\n\n            # Print Assistant thoughts\n            if assistant_reply_json != {}:\n                validate_json(assistant_reply_json, LLM_DEFAULT_RESPONSE_FORMAT)\n                # Get command name and arguments\n                try:\n                    print_assistant_thoughts(\n                        self.ai_name, assistant_reply_json, cfg.speak_mode\n                    )\n                    command_name, arguments = get_command(assistant_reply_json)\n                    if cfg.speak_mode:\n                        say_text(f\"我想要执行 {command_name}\")\n\n                    arguments = self._resolve_pathlike_command_args(arguments)\n\n                except Exception as e:\n                    logger.error(\"Error: \\n\", str(e))\n\n            if not cfg.continuous_mode and self.next_action_count == 0:\n                # ### GET USER AUTHORIZATION TO EXECUTE COMMAND ###\n                # Get key press: Prompt the user to press enter to continue or escape\n                # to exit\n                self.user_input = \"\"\n                logger.typewriter_log(\n                    \"下一步: \",\n                    Fore.CYAN,\n                    f\"命令 = {Fore.CYAN}{command_name}{Style.RESET_ALL}  \"\n                    f\"参数 = {Fore.CYAN}{arguments}{Style.RESET_ALL}\",\n                )\n\n                logger.info(\n                    \"输入 'y' 授权执行命令, 'y -N' 执行N步持续模式, 's' 执行自我反馈命令 或\"\n                    \"'n' 退出程序, 或直接输入反馈 \"\n                    f\"{self.ai_name}...\"\n                )\n                while True:\n                    if cfg.chat_messages_enabled:\n                        console_input = clean_input(\"等待你的反馈中...\")\n                    else:\n                        console_input = clean_input(\n                            Fore.MAGENTA + \"输入:\" + Style.RESET_ALL\n                        )\n                    if console_input.lower().strip() == cfg.authorise_key:\n                        user_input = \"生成下一个命令的JSON\"\n                        break\n                    elif console_input.lower().strip() == \"s\":\n                        logger.typewriter_log(\n                            \"-=-=-=-=-=-=-= 思考, 推理, 计划于反思将会被AI助手校验 -=-=-=-=-=-=-=\",\n                            Fore.GREEN,\n                            \"\",\n                        )\n                        thoughts = assistant_reply_json.get(\"thoughts\", {})\n                        self_feedback_resp = self.get_self_feedback(\n                            thoughts, cfg.fast_llm_model\n                        )\n                        logger.typewriter_log(\n                            f\"自我反馈: {self_feedback_resp}\",\n                            Fore.YELLOW,\n                            \"\",\n                        )\n                        if self_feedback_resp[0].lower().strip() == cfg.authorise_key:\n                            user_input = \"生成下一个命令的JSON\"\n                        else:\n                            user_input = self_feedback_resp\n                        break\n                    elif console_input.lower().strip() == \"\":\n                        logger.warn(\"错误的输入格式.\")\n                        continue\n                    elif console_input.lower().startswith(f\"{cfg.authorise_key} -\"):\n                        try:\n                            self.next_action_count = abs(\n                                int(console_input.split(\" \")[1])\n                            )\n                            user_input = \"生成下一个命令的JSON\"\n                        except ValueError:\n                            logger.warn(\n                                \"错误的输入格式. 请输入 'y -n' n 代表\"\n                                \" 持续模式的步数.\"\n                            )\n                            continue\n                        break\n                    elif console_input.lower() == cfg.exit_key:\n                        user_input = \"EXIT\"\n                        break\n                    else:\n                        user_input = console_input\n                        command_name = \"human_feedback\"\n                        break\n\n                if user_input == \"生成下一个命令的JSON\":\n                    logger.typewriter_log(\n                        \"-=-=-=-=-=-=-= 命令被用户批准执行 -=-=-=-=-=-=-=\",\n                        Fore.MAGENTA,\n                        \"\",\n                    )\n                elif user_input == \"EXIT\" or \"exit\" or \"退出\":\n                    logger.info(\"Exiting...\")\n                    break\n            else:\n                # Print command\n                logger.typewriter_log(\n                    \"下一步: \",\n                    Fore.CYAN,\n                    f\"命令 = {Fore.CYAN}{command_name}{Style.RESET_ALL}\"\n                    f\"  参数 = {Fore.CYAN}{arguments}{Style.RESET_ALL}\",\n                )\n\n            # Execute command\n            if command_name is not None and command_name.lower().startswith(\"error\"):\n                result = (\n                    f\"Command {command_name} threw the following error: {arguments}\"\n                )\n            elif command_name == \"人类反馈\":\n                result = f\"人类反馈: {user_input}\"\n            else:\n                for plugin in cfg.plugins:\n                    if not plugin.can_handle_pre_command():\n                        continue\n                    command_name, arguments = plugin.pre_command(\n                        command_name, arguments\n                    )\n                command_result = execute_command(\n                    self.command_registry,\n                    command_name,\n                    arguments,\n                    self.config.prompt_generator,\n                )\n                result = f\"Command {command_name} returned: \" f\"{command_result}\"\n\n                result_tlength = count_string_tokens(\n                    str(command_result), cfg.fast_llm_model\n                )\n                memory_tlength = count_string_tokens(\n                    str(self.summary_memory), cfg.fast_llm_model\n                )\n                if result_tlength + memory_tlength + 600 > cfg.fast_token_limit:\n                    result = f\"Failure: command {command_name} returned too much output. \\\n                        Do not execute this command again with the same arguments.\"\n\n                for plugin in cfg.plugins:\n                    if not plugin.can_handle_post_command():\n                        continue\n                    result = plugin.post_command(command_name, result)\n                if self.next_action_count > 0:\n                    self.next_action_count -= 1\n\n            # Check if there's a result from the command append it to the message\n            # history\n            if result is not None:\n                self.full_message_history.append(create_chat_message(\"system\", result))\n                logger.typewriter_log(\"SYSTEM: \", Fore.YELLOW, result)\n            else:\n                self.full_message_history.append(\n                    create_chat_message(\"system\", \"无法执行命令\")\n                )\n                logger.typewriter_log(\n                    \"SYSTEM: \", Fore.YELLOW, \"无法执行命令\"\n                )\n\n    def _resolve_pathlike_command_args(self, command_args):\n        if \"directory\" in command_args and command_args[\"directory\"] in {\"\", \"/\"}:\n            command_args[\"directory\"] = str(self.workspace.root)\n        else:\n            for pathlike in [\"filename\", \"directory\", \"clone_path\"]:\n                if pathlike in command_args:\n                    command_args[pathlike] = str(\n                        self.workspace.get_path(command_args[pathlike])\n                    )\n        return command_args\n\n    def get_self_feedback(self, thoughts: dict, llm_model: str) -> str:\n        \"\"\"Generates a feedback response based on the provided thoughts dictionary.\n        This method takes in a dictionary of thoughts containing keys such as \"reasoning\",\n        \"plan\", \"thoughts\", and \"criticism\". It combines these elements into a single\n        feedback message and uses the create_chat_completion() function to generate a\n        response based on the input message.\n        Args:\n            thoughts (dict): A dictionary containing thought elements like reasoning,\n            plan, thoughts, and criticism.\n        Returns:\n            str: A feedback response generated using the provided thoughts dictionary.\n        \"\"\"\n        ai_role = self.config.ai_role\n\n        feedback_prompt = f\"下面是来自我的消息，我是一个AI助手，角色为： {ai_role}. 请评估提供的思考，推理，计划与反思. 如果这些内容可以准确的完成该角色的任务，请回复字母'Y'后面加上一个空格，然后请解释为什么是最优方案. 日过这些信息无法实现该角色的目标, 请提供一句或多句解释一下具体的问题与建议的解决方案.\"\n        reasoning = thoughts.get(\"推理\", \"\")\n        plan = thoughts.get(\"计划\", \"\")\n        thought = thoughts.get(\"思考\", \"\")\n        criticism = thoughts.get(\"反思\", \"\")\n        feedback_thoughts = thought + reasoning + plan + criticism\n        return create_chat_completion(\n            [{\"role\": \"user\", \"content\": feedback_prompt + feedback_thoughts}],\n            llm_model,\n        )\n"
  },
  {
    "path": "autogpt/agent/agent_manager.py",
    "content": "\"\"\"Agent manager for managing GPT agents\"\"\"\nfrom __future__ import annotations\n\nfrom typing import List\n\nfrom autogpt.config.config import Config\nfrom autogpt.llm import Message, create_chat_completion\nfrom autogpt.singleton import Singleton\n\n\nclass AgentManager(metaclass=Singleton):\n    \"\"\"Agent manager for managing GPT agents\"\"\"\n\n    def __init__(self):\n        self.next_key = 0\n        self.agents = {}  # key, (task, full_message_history, model)\n        self.cfg = Config()\n\n    # Create new GPT agent\n    # TODO: Centralise use of create_chat_completion() to globally enforce token limit\n\n    def create_agent(self, task: str, prompt: str, model: str) -> tuple[int, str]:\n        \"\"\"Create a new agent and return its key\n\n        Args:\n            task: The task to perform\n            prompt: The prompt to use\n            model: The model to use\n\n        Returns:\n            The key of the new agent\n        \"\"\"\n        messages: List[Message] = [\n            {\"role\": \"user\", \"content\": prompt},\n        ]\n        for plugin in self.cfg.plugins:\n            if not plugin.can_handle_pre_instruction():\n                continue\n            if plugin_messages := plugin.pre_instruction(messages):\n                messages.extend(iter(plugin_messages))\n        # Start GPT instance\n        agent_reply = create_chat_completion(\n            model=model,\n            messages=messages,\n        )\n\n        messages.append({\"role\": \"assistant\", \"content\": agent_reply})\n\n        plugins_reply = \"\"\n        for i, plugin in enumerate(self.cfg.plugins):\n            if not plugin.can_handle_on_instruction():\n                continue\n            if plugin_result := plugin.on_instruction(messages):\n                sep = \"\\n\" if i else \"\"\n                plugins_reply = f\"{plugins_reply}{sep}{plugin_result}\"\n\n        if plugins_reply and plugins_reply != \"\":\n            messages.append({\"role\": \"assistant\", \"content\": plugins_reply})\n        key = self.next_key\n        # This is done instead of len(agents) to make keys unique even if agents\n        # are deleted\n        self.next_key += 1\n\n        self.agents[key] = (task, messages, model)\n\n        for plugin in self.cfg.plugins:\n            if not plugin.can_handle_post_instruction():\n                continue\n            agent_reply = plugin.post_instruction(agent_reply)\n\n        return key, agent_reply\n\n    def message_agent(self, key: str | int, message: str) -> str:\n        \"\"\"Send a message to an agent and return its response\n\n        Args:\n            key: The key of the agent to message\n            message: The message to send to the agent\n\n        Returns:\n            The agent's response\n        \"\"\"\n        task, messages, model = self.agents[int(key)]\n\n        # Add user message to message history before sending to agent\n        messages.append({\"role\": \"user\", \"content\": message})\n\n        for plugin in self.cfg.plugins:\n            if not plugin.can_handle_pre_instruction():\n                continue\n            if plugin_messages := plugin.pre_instruction(messages):\n                for plugin_message in plugin_messages:\n                    messages.append(plugin_message)\n\n        # Start GPT instance\n        agent_reply = create_chat_completion(\n            model=model,\n            messages=messages,\n        )\n\n        messages.append({\"role\": \"assistant\", \"content\": agent_reply})\n\n        plugins_reply = agent_reply\n        for i, plugin in enumerate(self.cfg.plugins):\n            if not plugin.can_handle_on_instruction():\n                continue\n            if plugin_result := plugin.on_instruction(messages):\n                sep = \"\\n\" if i else \"\"\n                plugins_reply = f\"{plugins_reply}{sep}{plugin_result}\"\n        # Update full message history\n        if plugins_reply and plugins_reply != \"\":\n            messages.append({\"role\": \"assistant\", \"content\": plugins_reply})\n\n        for plugin in self.cfg.plugins:\n            if not plugin.can_handle_post_instruction():\n                continue\n            agent_reply = plugin.post_instruction(agent_reply)\n\n        return agent_reply\n\n    def list_agents(self) -> list[tuple[str | int, str]]:\n        \"\"\"Return a list of all agents\n\n        Returns:\n            A list of tuples of the form (key, task)\n        \"\"\"\n\n        # Return a list of agent keys and their tasks\n        return [(key, task) for key, (task, _, _) in self.agents.items()]\n\n    def delete_agent(self, key: str | int) -> bool:\n        \"\"\"Delete an agent from the agent manager\n\n        Args:\n            key: The key of the agent to delete\n\n        Returns:\n            True if successful, False otherwise\n        \"\"\"\n\n        try:\n            del self.agents[int(key)]\n            return True\n        except KeyError:\n            return False\n"
  },
  {
    "path": "autogpt/app.py",
    "content": "\"\"\" Command and Control \"\"\"\nimport json\nfrom typing import Dict, List, NoReturn, Union\n\nfrom autogpt.agent.agent_manager import AgentManager\nfrom autogpt.commands.command import CommandRegistry, command\nfrom autogpt.commands.web_requests import scrape_links, scrape_text\nfrom autogpt.config import Config\nfrom autogpt.logs import logger\nfrom autogpt.memory import get_memory\nfrom autogpt.processing.text import summarize_text\nfrom autogpt.prompts.generator import PromptGenerator\nfrom autogpt.speech import say_text\nfrom autogpt.url_utils.validators import validate_url\n\nCFG = Config()\nAGENT_MANAGER = AgentManager()\n\n\ndef is_valid_int(value: str) -> bool:\n    \"\"\"Check if the value is a valid integer\n\n    Args:\n        value (str): The value to check\n\n    Returns:\n        bool: True if the value is a valid integer, False otherwise\n    \"\"\"\n    try:\n        int(value)\n        return True\n    except ValueError:\n        return False\n\n\ndef get_command(response_json: Dict):\n    \"\"\"Parse the response and return the command name and arguments\n\n    Args:\n        response_json (json): The response from the AI\n\n    Returns:\n        tuple: The command name and arguments\n\n    Raises:\n        json.decoder.JSONDecodeError: If the response is not valid JSON\n\n        Exception: If any other error occurs\n    \"\"\"\n    try:\n        if \"command\" not in response_json:\n            return \"Error:\", \"缺少 'command' object in JSON\"\n\n        if not isinstance(response_json, dict):\n            return \"Error:\", f\"'response_json' object is not dictionary {response_json}\"\n\n        command = response_json[\"command\"]\n        if not isinstance(command, dict):\n            return \"Error:\", \"'command' object is not a dictionary\"\n\n        if \"name\" not in command:\n            return \"Error:\", \"缺少 'name' field in 'command' object\"\n\n        command_name = command[\"name\"]\n\n        # Use an empty dictionary if 'args' field is not present in 'command' object\n        arguments = command.get(\"args\", {})\n\n        return command_name, arguments\n    except json.decoder.JSONDecodeError:\n        return \"Error:\", \"Invalid JSON\"\n    # All other errors, return \"Error: + error message\"\n    except Exception as e:\n        return \"Error:\", str(e)\n\n\ndef map_command_synonyms(command_name: str):\n    \"\"\"Takes the original command name given by the AI, and checks if the\n    string matches a list of common/known hallucinations\n    \"\"\"\n    synonyms = [\n        (\"write_file\", \"write_to_file\"),\n        (\"create_file\", \"write_to_file\"),\n        (\"search\", \"google\"),\n    ]\n    for seen_command, actual_command_name in synonyms:\n        if command_name == seen_command:\n            return actual_command_name\n    return command_name\n\n\ndef execute_command(\n    command_registry: CommandRegistry,\n    command_name: str,\n    arguments,\n    prompt: PromptGenerator,\n):\n    \"\"\"Execute the command and return the result\n\n    Args:\n        command_name (str): The name of the command to execute\n        arguments (dict): The arguments for the command\n\n    Returns:\n        str: The result of the command\n    \"\"\"\n    try:\n        cmd = command_registry.commands.get(command_name)\n\n        # If the command is found, call it with the provided arguments\n        if cmd:\n            return cmd(**arguments)\n\n        # TODO: Remove commands below after they are moved to the command registry.\n        command_name = map_command_synonyms(command_name.lower())\n\n        if command_name == \"memory_add\":\n            return get_memory(CFG).add(arguments[\"string\"])\n\n        # TODO: Change these to take in a file rather than pasted code, if\n        # non-file is given, return instructions \"Input should be a python\n        # filepath, write your code to file and try again\n        else:\n            for command in prompt.commands:\n                if (\n                    command_name == command[\"label\"].lower()\n                    or command_name == command[\"name\"].lower()\n                ):\n                    return command[\"function\"](**arguments)\n            return (\n                f\"Unknown command '{command_name}'. Please refer to the 'COMMANDS'\"\n                \" list for available commands and only respond in the specified JSON\"\n                \" format.\"\n            )\n    except Exception as e:\n        return f\"错误: {str(e)}\"\n\n\n@command(\n    \"get_text_summary\", \"Get text summary\", '\"url\": \"<url>\", \"question\": \"<question>\"'\n)\n@validate_url\ndef get_text_summary(url: str, question: str) -> str:\n    \"\"\"Return the results of a Google search\n\n    Args:\n        url (str): The url to scrape\n        question (str): The question to summarize the text for\n\n    Returns:\n        str: The summary of the text\n    \"\"\"\n    text = scrape_text(url)\n    summary = summarize_text(url, text, question)\n    return f\"\"\" \"结果\" : {summary}\"\"\"\n\n\n@command(\"get_hyperlinks\", \"Get text summary\", '\"url\": \"<url>\"')\n@validate_url\ndef get_hyperlinks(url: str) -> Union[str, List[str]]:\n    \"\"\"Return the results of a Google search\n\n    Args:\n        url (str): The url to scrape\n\n    Returns:\n        str or list: The hyperlinks on the page\n    \"\"\"\n    return scrape_links(url)\n\n\n@command(\n    \"start_agent\",\n    \"启动GPT助手\",\n    '\"name\": \"<name>\", \"task\": \"<short_task_desc>\", \"prompt\": \"<prompt>\"',\n)\ndef start_agent(name: str, task: str, prompt: str, model=CFG.fast_llm_model) -> str:\n    \"\"\"Start an agent with a given name, task, and prompt\n\n    Args:\n        name (str): The name of the agent\n        task (str): The task of the agent\n        prompt (str): The prompt for the agent\n        model (str): The model to use for the agent\n\n    Returns:\n        str: The response of the agent\n    \"\"\"\n    # Remove underscores from name\n    voice_name = name.replace(\"_\", \" \")\n\n    first_message = f\"\"\"你是 {name}.  回答 with: \"收到\".\"\"\"\n    agent_intro = f\"{voice_name} 在这儿呢, 听从领导指挥!\"\n\n    # Create agent\n    if CFG.speak_mode:\n        say_text(agent_intro, 1)\n    key, ack = AGENT_MANAGER.create_agent(task, first_message, model)\n\n    if CFG.speak_mode:\n        say_text(f\"你好 {voice_name}. 你的任务如下. {task}.\")\n\n    # Assign task (prompt), get response\n    agent_response = AGENT_MANAGER.message_agent(key, prompt)\n\n    return f\"Agent {name} 生成key {key}. 首次反馈: {agent_response}\"\n\n\n@command(\"message_agent\", \"Message GPT Agent\", '\"key\": \"<key>\", \"message\": \"<message>\"')\ndef message_agent(key: str, message: str) -> str:\n    \"\"\"Message an agent with a given key and message\"\"\"\n    # Check if the key is a valid integer\n    if is_valid_int(key):\n        agent_response = AGENT_MANAGER.message_agent(int(key), message)\n    else:\n        return \"无效的key, 必须为数字.\"\n\n    # Speak response\n    if CFG.speak_mode:\n        say_text(agent_response, 1)\n    return agent_response\n\n\n@command(\"list_agents\", \"List GPT Agents\", \"\")\ndef list_agents() -> str:\n    \"\"\"List all agents\n\n    Returns:\n        str: A list of all agents\n    \"\"\"\n    return \"List of agents:\\n\" + \"\\n\".join(\n        [str(x[0]) + \": \" + x[1] for x in AGENT_MANAGER.list_agents()]\n    )\n\n\n@command(\"delete_agent\", \"Delete GPT Agent\", '\"key\": \"<key>\"')\ndef delete_agent(key: str) -> str:\n    \"\"\"Delete an agent with a given key\n\n    Args:\n        key (str): The key of the agent to delete\n\n    Returns:\n        str: A message indicating whether the agent was deleted or not\n    \"\"\"\n    result = AGENT_MANAGER.delete_agent(key)\n    return f\"Agent {key} deleted.\" if result else f\"Agent {key} does not exist.\"\n"
  },
  {
    "path": "autogpt/cli.py",
    "content": "\"\"\"Main script for the autogpt package.\"\"\"\nimport click\n\n\n@click.group(invoke_without_command=True)\n@click.option(\"-c\", \"--continuous\", is_flag=True, help=\"启动持续模式\")\n@click.option(\n    \"--skip-reprompt\",\n    \"-y\",\n    is_flag=True,\n    help=\"跳过重新输入命令环节\",\n)\n@click.option(\n    \"--ai-settings\",\n    \"-C\",\n    help=\"指定使用哪个ai_settings.yaml文件, 同时自动跳过重新输入命令.\",\n)\n@click.option(\n    \"-l\",\n    \"--continuous-limit\",\n    type=int,\n    help=\"定义持续模式中的持续次数\",\n)\n@click.option(\"--speak\", is_flag=True, help=\"开启语音模式\")\n@click.option(\"--debug\", is_flag=True, help=\"开启Debug模式\")\n@click.option(\"--gpt3only\", is_flag=True, help=\"开启GPT3.5模式\")\n@click.option(\"--gpt4only\", is_flag=True, help=\"开启GPT4模式\")\n@click.option(\n    \"--use-memory\",\n    \"-m\",\n    \"memory_type\",\n    type=str,\n    help=\"定义使用那种记忆后台\",\n)\n@click.option(\n    \"-b\",\n    \"--browser-name\",\n    help=\"指定使用哪个 Web 浏览器来使用 Selenium 抓取网络内容.\",\n)\n@click.option(\n    \"--allow-downloads\",\n    is_flag=True,\n    help=\"危险: 允许Auto-GPT自动下载文件.\",\n)\n@click.option(\n    \"--skip-news\",\n    is_flag=True,\n    help=\"指定是否在启动时不输出最新新闻.\",\n)\n@click.option(\n    # TODO: this is a hidden option for now, necessary for integration testing.\n    #   We should make this public once we're ready to roll out agent specific workspaces.\n    \"--workspace-directory\",\n    \"-w\",\n    type=click.Path(),\n    hidden=True,\n)\n@click.option(\n    \"--install-plugin-deps\",\n    is_flag=True,\n    help=\"为第三方插件安装外部依赖库.\",\n)\n@click.pass_context\ndef main(\n    ctx: click.Context,\n    continuous: bool,\n    continuous_limit: int,\n    ai_settings: str,\n    skip_reprompt: bool,\n    speak: bool,\n    debug: bool,\n    gpt3only: bool,\n    gpt4only: bool,\n    memory_type: str,\n    browser_name: str,\n    allow_downloads: bool,\n    skip_news: bool,\n    workspace_directory: str,\n    install_plugin_deps: bool,\n) -> None:\n    \"\"\"\n    Welcome to AutoGPT an experimental open-source application showcasing the capabilities of the GPT-4 pushing the boundaries of AI.\n\n    Start an Auto-GPT assistant.\n    \"\"\"\n    # Put imports inside function to avoid importing everything when starting the CLI\n    from autogpt.main import run_auto_gpt\n\n    if ctx.invoked_subcommand is None:\n        run_auto_gpt(\n            continuous,\n            continuous_limit,\n            ai_settings,\n            skip_reprompt,\n            speak,\n            debug,\n            gpt3only,\n            gpt4only,\n            memory_type,\n            browser_name,\n            allow_downloads,\n            skip_news,\n            workspace_directory,\n            install_plugin_deps,\n        )\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "autogpt/commands/__init__.py",
    "content": ""
  },
  {
    "path": "autogpt/commands/analyze_code.py",
    "content": "\"\"\"Code evaluation module.\"\"\"\nfrom __future__ import annotations\n\nfrom autogpt.commands.command import command\nfrom autogpt.llm import call_ai_function\n\n\n@command(\n    \"analyze_code\",\n    \"分析代码\",\n    '\"code\": \"<full_code_string>\"',\n)\ndef analyze_code(code: str) -> list[str]:\n    \"\"\"\n    A function that takes in a string and returns a response from create chat\n      completion api call.\n\n    Parameters:\n        code (str): Code to be evaluated.\n    Returns:\n        A result string from create chat completion. A list of suggestions to\n            improve the code.\n    \"\"\"\n\n    function_string = \"def analyze_code(code: str) -> list[str]:\"\n    args = [code]\n    description_string = (\n        \"分析给出的代码并列出一系列优化建议。\"\n    )\n\n    return call_ai_function(function_string, args, description_string)\n"
  },
  {
    "path": "autogpt/commands/audio_text.py",
    "content": "\"\"\"Commands for converting audio to text.\"\"\"\nimport json\n\nimport requests\n\nfrom autogpt.commands.command import command\nfrom autogpt.config import Config\n\nCFG = Config()\n\n\n@command(\n    \"read_audio_from_file\",\n    \"转换音频至文本\",\n    '\"文件名\": \"<filename>\"',\n    CFG.huggingface_audio_to_text_model,\n    \"Configure huggingface_audio_to_text_model.\",\n)\ndef read_audio_from_file(filename: str) -> str:\n    \"\"\"\n    Convert audio to text.\n\n    Args:\n        filename (str): The path to the audio file\n\n    Returns:\n        str: The text from the audio\n    \"\"\"\n    with open(filename, \"rb\") as audio_file:\n        audio = audio_file.read()\n    return read_audio(audio)\n\n\ndef read_audio(audio: bytes) -> str:\n    \"\"\"\n    Convert audio to text.\n\n    Args:\n        audio (bytes): The audio to convert\n\n    Returns:\n        str: The text from the audio\n    \"\"\"\n    model = CFG.huggingface_audio_to_text_model\n    api_url = f\"https://api-inference.huggingface.co/models/{model}\"\n    api_token = CFG.huggingface_api_token\n    headers = {\"Authorization\": f\"Bearer {api_token}\"}\n\n    if api_token is None:\n        raise ValueError(\n            \"你需要在配置文件中配置你的Hugging Face API token.\"\n        )\n\n    response = requests.post(\n        api_url,\n        headers=headers,\n        data=audio,\n    )\n\n    text = json.loads(response.content.decode(\"utf-8\"))[\"text\"]\n    return f\"音频中说道: {text}\"\n"
  },
  {
    "path": "autogpt/commands/command.py",
    "content": "import functools\nimport importlib\nimport inspect\nfrom typing import Any, Callable, Optional\n\n# Unique identifier for auto-gpt commands\nAUTO_GPT_COMMAND_IDENTIFIER = \"auto_gpt_command\"\n\n\nclass Command:\n    \"\"\"A class representing a command.\n\n    Attributes:\n        name (str): The name of the command.\n        description (str): A brief description of what the command does.\n        signature (str): The signature of the function that the command executes. Defaults to None.\n    \"\"\"\n\n    def __init__(\n        self,\n        name: str,\n        description: str,\n        method: Callable[..., Any],\n        signature: str = \"\",\n        enabled: bool = True,\n        disabled_reason: Optional[str] = None,\n    ):\n        self.name = name\n        self.description = description\n        self.method = method\n        self.signature = signature if signature else str(inspect.signature(self.method))\n        self.enabled = enabled\n        self.disabled_reason = disabled_reason\n\n    def __call__(self, *args, **kwargs) -> Any:\n        if not self.enabled:\n            return f\"命令 '{self.name}' 被禁止: {self.disabled_reason}\"\n        return self.method(*args, **kwargs)\n\n    def __str__(self) -> str:\n        return f\"{self.name}: {self.description}, args: {self.signature}\"\n\n\nclass CommandRegistry:\n    \"\"\"\n    The CommandRegistry class is a manager for a collection of Command objects.\n    It allows the registration, modification, and retrieval of Command objects,\n    as well as the scanning and loading of command plugins from a specified\n    directory.\n    \"\"\"\n\n    def __init__(self):\n        self.commands = {}\n\n    def _import_module(self, module_name: str) -> Any:\n        return importlib.import_module(module_name)\n\n    def _reload_module(self, module: Any) -> Any:\n        return importlib.reload(module)\n\n    def register(self, cmd: Command) -> None:\n        self.commands[cmd.name] = cmd\n\n    def unregister(self, command_name: str):\n        if command_name in self.commands:\n            del self.commands[command_name]\n        else:\n            raise KeyError(f\"命令 '{command_name}' 在注册表中未找到.\")\n\n    def reload_commands(self) -> None:\n        \"\"\"Reloads all loaded command plugins.\"\"\"\n        for cmd_name in self.commands:\n            cmd = self.commands[cmd_name]\n            module = self._import_module(cmd.__module__)\n            reloaded_module = self._reload_module(module)\n            if hasattr(reloaded_module, \"register\"):\n                reloaded_module.register(self)\n\n    def get_command(self, name: str) -> Callable[..., Any]:\n        return self.commands[name]\n\n    def call(self, command_name: str, **kwargs) -> Any:\n        if command_name not in self.commands:\n            raise KeyError(f\"文件 '{command_name}' 在注册表中未找到.\")\n        command = self.commands[command_name]\n        return command(**kwargs)\n\n    def command_prompt(self) -> str:\n        \"\"\"\n        Returns a string representation of all registered `Command` objects for use in a prompt\n        \"\"\"\n        commands_list = [\n            f\"{idx + 1}. {str(cmd)}\" for idx, cmd in enumerate(self.commands.values())\n        ]\n        return \"\\n\".join(commands_list)\n\n    def import_commands(self, module_name: str) -> None:\n        \"\"\"\n        Imports the specified Python module containing command plugins.\n\n        This method imports the associated module and registers any functions or\n        classes that are decorated with the `AUTO_GPT_COMMAND_IDENTIFIER` attribute\n        as `Command` objects. The registered `Command` objects are then added to the\n        `commands` dictionary of the `CommandRegistry` object.\n\n        Args:\n            module_name (str): The name of the module to import for command plugins.\n        \"\"\"\n\n        module = importlib.import_module(module_name)\n\n        for attr_name in dir(module):\n            attr = getattr(module, attr_name)\n            # Register decorated functions\n            if hasattr(attr, AUTO_GPT_COMMAND_IDENTIFIER) and getattr(\n                attr, AUTO_GPT_COMMAND_IDENTIFIER\n            ):\n                self.register(attr.command)\n            # Register command classes\n            elif (\n                inspect.isclass(attr) and issubclass(attr, Command) and attr != Command\n            ):\n                cmd_instance = attr()\n                self.register(cmd_instance)\n\n\ndef command(\n    name: str,\n    description: str,\n    signature: str = \"\",\n    enabled: bool = True,\n    disabled_reason: Optional[str] = None,\n) -> Callable[..., Any]:\n    \"\"\"The command decorator is used to create Command objects from ordinary functions.\"\"\"\n\n    def decorator(func: Callable[..., Any]) -> Command:\n        cmd = Command(\n            name=name,\n            description=description,\n            method=func,\n            signature=signature,\n            enabled=enabled,\n            disabled_reason=disabled_reason,\n        )\n\n        @functools.wraps(func)\n        def wrapper(*args, **kwargs) -> Any:\n            return func(*args, **kwargs)\n\n        wrapper.command = cmd\n\n        setattr(wrapper, AUTO_GPT_COMMAND_IDENTIFIER, True)\n\n        return wrapper\n\n    return decorator\n"
  },
  {
    "path": "autogpt/commands/execute_code.py",
    "content": "\"\"\"Execute code in a Docker container\"\"\"\nimport os\nimport subprocess\nfrom pathlib import Path\n\nimport docker\nfrom docker.errors import ImageNotFound\n\nfrom autogpt.commands.command import command\nfrom autogpt.config import Config\nfrom autogpt.logs import logger\n\nCFG = Config()\n\n\n@command(\"execute_python_file\", \"Execute Python File\", '\"filename\": \"<filename>\"')\ndef execute_python_file(filename: str) -> str:\n    \"\"\"Execute a Python file in a Docker container and return the output\n\n    Args:\n        filename (str): The name of the file to execute\n\n    Returns:\n        str: The output of the file\n    \"\"\"\n    logger.info(f\"执行文件中 '{filename}'\")\n\n    if not filename.endswith(\".py\"):\n        return \"错误: 无效的文件类型. 只允许 .py文件.\"\n\n    if not os.path.isfile(filename):\n        return f\"错误: 文件 '{filename}' 不存在.\"\n\n    if we_are_running_in_a_docker_container():\n        result = subprocess.run(\n            f\"python {filename}\", capture_output=True, encoding=\"utf8\", shell=True\n        )\n        if result.returncode == 0:\n            return result.stdout\n        else:\n            return f\"错误: {result.stderr}\"\n\n    try:\n        client = docker.from_env()\n        # You can replace this with the desired Python image/version\n        # You can find available Python images on Docker Hub:\n        # https://hub.docker.com/_/python\n        image_name = \"python:3-alpine\"\n        try:\n            client.images.get(image_name)\n            logger.warn(f\"Image '{image_name}' found locally\")\n        except ImageNotFound:\n            logger.info(\n                f\"Image '{image_name}' not found locally, pulling from Docker Hub\"\n            )\n            # Use the low-level API to stream the pull response\n            low_level_client = docker.APIClient()\n            for line in low_level_client.pull(image_name, stream=True, decode=True):\n                # Print the status and progress, if available\n                status = line.get(\"status\")\n                progress = line.get(\"progress\")\n                if status and progress:\n                    logger.info(f\"{status}: {progress}\")\n                elif status:\n                    logger.info(status)\n        container = client.containers.run(\n            image_name,\n            f\"python {Path(filename).relative_to(CFG.workspace_path)}\",\n            volumes={\n                CFG.workspace_path: {\n                    \"bind\": \"/workspace\",\n                    \"mode\": \"ro\",\n                }\n            },\n            working_dir=\"/workspace\",\n            stderr=True,\n            stdout=True,\n            detach=True,\n        )\n\n        container.wait()\n        logs = container.logs().decode(\"utf-8\")\n        container.remove()\n\n        # print(f\"Execution complete. Output: {output}\")\n        # print(f\"Logs: {logs}\")\n\n        return logs\n\n    except docker.errors.DockerException as e:\n        logger.warn(\n            \"在容器中无法执行脚本. 如果你还没有安装，请安装Docker https://docs.docker.com/get-docker/\"\n        )\n        return f\"错误: {str(e)}\"\n\n    except Exception as e:\n        return f\"错误: {str(e)}\"\n\n\n@command(\n    \"execute_shell\",\n    \"Execute Shell Command, non-interactive commands only\",\n    '\"command_line\": \"<command_line>\"',\n    CFG.execute_local_commands,\n    \"You are not allowed to run local shell commands. To execute\"\n    \" shell commands, EXECUTE_LOCAL_COMMANDS must be set to 'True' \"\n    \"in your config. Do not attempt to bypass the restriction.\",\n)\ndef execute_shell(command_line: str) -> str:\n    \"\"\"Execute a shell command and return the output\n\n    Args:\n        command_line (str): The command line to execute\n\n    Returns:\n        str: The output of the command\n    \"\"\"\n\n    current_dir = Path.cwd()\n    # Change dir into workspace if necessary\n    if not current_dir.is_relative_to(CFG.workspace_path):\n        os.chdir(CFG.workspace_path)\n\n    logger.info(\n        f\"执行命令  '{command_line}' in working directory '{os.getcwd()}'\"\n    )\n\n    result = subprocess.run(command_line, capture_output=True, shell=True)\n    output = f\"STDOUT:\\n{result.stdout}\\nSTDERR:\\n{result.stderr}\"\n\n    # Change back to whatever the prior working dir was\n\n    os.chdir(current_dir)\n    return output\n\n\n@command(\n    \"execute_shell_popen\",\n    \"Execute Shell Command, non-interactive commands only\",\n    '\"command_line\": \"<command_line>\"',\n    CFG.execute_local_commands,\n    \"You are not allowed to run local shell commands. To execute\"\n    \" shell commands, EXECUTE_LOCAL_COMMANDS must be set to 'True' \"\n    \"in your config. Do not attempt to bypass the restriction.\",\n)\ndef execute_shell_popen(command_line) -> str:\n    \"\"\"Execute a shell command with Popen and returns an english description\n    of the event and the process id\n\n    Args:\n        command_line (str): The command line to execute\n\n    Returns:\n        str: Description of the fact that the process started and its id\n    \"\"\"\n\n    current_dir = os.getcwd()\n    # Change dir into workspace if necessary\n    if CFG.workspace_path not in current_dir:\n        os.chdir(CFG.workspace_path)\n\n    logger.info(\n        f\"Executing command '{command_line}' in working directory '{os.getcwd()}'\"\n    )\n\n    do_not_show_output = subprocess.DEVNULL\n    process = subprocess.Popen(\n        command_line, shell=True, stdout=do_not_show_output, stderr=do_not_show_output\n    )\n\n    # Change back to whatever the prior working dir was\n\n    os.chdir(current_dir)\n\n    return f\"Subprocess started with PID:'{str(process.pid)}'\"\n\n\ndef we_are_running_in_a_docker_container() -> bool:\n    \"\"\"Check if we are running in a Docker container\n\n    Returns:\n        bool: True if we are running in a Docker container, False otherwise\n    \"\"\"\n    return os.path.exists(\"/.dockerenv\")\n"
  },
  {
    "path": "autogpt/commands/file_operations.py",
    "content": "\"\"\"File operations for AutoGPT\"\"\"\nfrom __future__ import annotations\n\nimport hashlib\nimport os\nimport os.path\nfrom typing import Dict, Generator, Literal, Tuple\n\nimport charset_normalizer\nimport requests\nfrom colorama import Back, Fore\nfrom requests.adapters import HTTPAdapter, Retry\n\nfrom autogpt.commands.command import command\nfrom autogpt.config import Config\nfrom autogpt.logs import logger\nfrom autogpt.spinner import Spinner\nfrom autogpt.utils import readable_file_size\n\nCFG = Config()\n\nOperation = Literal[\"write\", \"append\", \"delete\"]\n\n\ndef text_checksum(text: str) -> str:\n    \"\"\"Get the hex checksum for the given text.\"\"\"\n    return hashlib.md5(text.encode(\"utf-8\")).hexdigest()\n\n\ndef operations_from_log(log_path: str) -> Generator[Tuple[Operation, str, str | None]]:\n    \"\"\"Parse the file operations log and return a tuple containing the log entries\"\"\"\n    try:\n        log = open(log_path, \"r\", encoding=\"utf-8\")\n    except FileNotFoundError:\n        return\n\n    for line in log:\n        line = line.replace(\"File Operation Logger\", \"\").strip()\n        if not line:\n            continue\n        operation, tail = line.split(\": \", maxsplit=1)\n        operation = operation.strip()\n        if operation in (\"write\", \"append\"):\n            try:\n                path, checksum = (x.strip() for x in tail.rsplit(\" #\", maxsplit=1))\n            except ValueError:\n                path, checksum = tail.strip(), None\n            yield (operation, path, checksum)\n        elif operation == \"delete\":\n            yield (operation, tail.strip(), None)\n\n    log.close()\n\n\ndef file_operations_state(log_path: str) -> Dict:\n    \"\"\"Iterates over the operations log and returns the expected state.\n\n    Parses a log file at CFG.file_logger_path to construct a dictionary that maps\n    each file path written or appended to its checksum. Deleted files are removed\n    from the dictionary.\n\n    Returns:\n        A dictionary mapping file paths to their checksums.\n\n    Raises:\n        FileNotFoundError: If CFG.file_logger_path is not found.\n        ValueError: If the log file content is not in the expected format.\n    \"\"\"\n    state = {}\n    for operation, path, checksum in operations_from_log(log_path):\n        if operation in (\"write\", \"append\"):\n            state[path] = checksum\n        elif operation == \"delete\":\n            del state[path]\n    return state\n\n\ndef is_duplicate_operation(\n    operation: Operation, filename: str, checksum: str | None = None\n) -> bool:\n    \"\"\"Check if the operation has already been performed\n\n    Args:\n        operation: The operation to check for\n        filename: The name of the file to check for\n        checksum: The checksum of the contents to be written\n\n    Returns:\n        True if the operation has already been performed on the file\n    \"\"\"\n    state = file_operations_state(CFG.file_logger_path)\n    if operation == \"delete\" and filename not in state:\n        return True\n    if operation == \"write\" and state.get(filename) == checksum:\n        return True\n    return False\n\n\ndef log_operation(operation: str, filename: str, checksum: str | None = None) -> None:\n    \"\"\"Log the file operation to the file_logger.txt\n\n    Args:\n        operation: The operation to log\n        filename: The name of the file the operation was performed on\n        checksum: The checksum of the contents to be written\n    \"\"\"\n    log_entry = f\"{operation}: {filename}\"\n    if checksum is not None:\n        log_entry += f\" #{checksum}\"\n    logger.debug(f\"Logging file operation: {log_entry}\")\n    append_to_file(CFG.file_logger_path, f\"{log_entry}\\n\", should_log=False)\n\n\ndef split_file(\n    content: str, max_length: int = 4000, overlap: int = 0\n) -> Generator[str, None, None]:\n    \"\"\"\n    Split text into chunks of a specified maximum length with a specified overlap\n    between chunks.\n\n    :param content: The input text to be split into chunks\n    :param max_length: The maximum length of each chunk,\n        default is 4000 (about 1k token)\n    :param overlap: The number of overlapping characters between chunks,\n        default is no overlap\n    :return: A generator yielding chunks of text\n    \"\"\"\n    start = 0\n    content_length = len(content)\n\n    while start < content_length:\n        end = start + max_length\n        if end + overlap < content_length:\n            chunk = content[start : end + overlap - 1]\n        else:\n            chunk = content[start:content_length]\n\n            # Account for the case where the last chunk is shorter than the overlap, so it has already been consumed\n            if len(chunk) <= overlap:\n                break\n\n        yield chunk\n        start += max_length - overlap\n\n\n@command(\"read_file\", \"Read file\", '\"filename\": \"<filename>\"')\ndef read_file(filename: str) -> str:\n    \"\"\"Read a file and return the contents\n\n    Args:\n        filename (str): The name of the file to read\n\n    Returns:\n        str: The contents of the file\n    \"\"\"\n    try:\n        charset_match = charset_normalizer.from_path(filename).best()\n        encoding = charset_match.encoding\n        logger.debug(f\"Read file '{filename}' with encoding '{encoding}'\")\n        return str(charset_match)\n    except Exception as err:\n        return f\"错误: {err}\"\n\n\ndef ingest_file(\n    filename: str, memory, max_length: int = 4000, overlap: int = 200\n) -> None:\n    \"\"\"\n    Ingest a file by reading its content, splitting it into chunks with a specified\n    maximum length and overlap, and adding the chunks to the memory storage.\n\n    :param filename: The name of the file to ingest\n    :param memory: An object with an add() method to store the chunks in memory\n    :param max_length: The maximum length of each chunk, default is 4000\n    :param overlap: The number of overlapping characters between chunks, default is 200\n    \"\"\"\n    try:\n        logger.info(f\"操作文件中 {filename}\")\n        content = read_file(filename)\n        content_length = len(content)\n        logger.info(f\"文件长度: {content_length} 字符\")\n\n        chunks = list(split_file(content, max_length=max_length, overlap=overlap))\n\n        num_chunks = len(chunks)\n        for i, chunk in enumerate(chunks):\n            logger.info(f\"注入块 {i + 1} / {num_chunks} 到记忆中\")\n            memory_to_add = (\n                f\"文件名: {filename}\\n\" f\"内容块#{i + 1}/{num_chunks}: {chunk}\"\n            )\n\n            memory.add(memory_to_add)\n\n        logger.info(f\"注入完成 {num_chunks} 块 from {filename}.\")\n    except Exception as err:\n        logger.info(f\"注入文件出现错误 '{filename}': {err}\")\n\n\n@command(\"write_to_file\", \"Write to file\", '\"filename\": \"<filename>\", \"text\": \"<text>\"')\ndef write_to_file(filename: str, text: str) -> str:\n    \"\"\"Write text to a file\n\n    Args:\n        filename (str): The name of the file to write to\n        text (str): The text to write to the file\n\n    Returns:\n        str: A message indicating success or failure\n    \"\"\"\n    checksum = text_checksum(text)\n    if is_duplicate_operation(\"write\", filename, checksum):\n        return \"错误: 文件已经更新.\"\n    try:\n        directory = os.path.dirname(filename)\n        os.makedirs(directory, exist_ok=True)\n        with open(filename, \"w\", encoding=\"utf-8\") as f:\n            f.write(text)\n        log_operation(\"write\", filename, checksum)\n        return \"文件写入成功.\"\n    except Exception as err:\n        return f\"错误: {err}\"\n\n\n@command(\n    \"append_to_file\", \"Append to file\", '\"filename\": \"<filename>\", \"text\": \"<text>\"'\n)\ndef append_to_file(filename: str, text: str, should_log: bool = True) -> str:\n    \"\"\"Append text to a file\n\n    Args:\n        filename (str): The name of the file to append to\n        text (str): The text to append to the file\n        should_log (bool): Should log output\n\n    Returns:\n        str: A message indicating success or failure\n    \"\"\"\n    try:\n        directory = os.path.dirname(filename)\n        os.makedirs(directory, exist_ok=True)\n        with open(filename, \"a\", encoding=\"utf-8\") as f:\n            f.write(text)\n\n        if should_log:\n            with open(filename, \"r\", encoding=\"utf-8\") as f:\n                checksum = text_checksum(f.read())\n            log_operation(\"append\", filename, checksum=checksum)\n\n        return \"文本追加成功.\"\n    except Exception as err:\n        return f\"错误: {err}\"\n\n\n@command(\"delete_file\", \"Delete file\", '\"filename\": \"<filename>\"')\ndef delete_file(filename: str) -> str:\n    \"\"\"Delete a file\n\n    Args:\n        filename (str): The name of the file to delete\n\n    Returns:\n        str: A message indicating success or failure\n    \"\"\"\n    if is_duplicate_operation(\"delete\", filename):\n        return \"错误: 文件已经删除.\"\n    try:\n        os.remove(filename)\n        log_operation(\"delete\", filename)\n        return \"文件删除成功.\"\n    except Exception as err:\n        return f\"错误: {err}\"\n\n\n@command(\"list_files\", \"List Files in Directory\", '\"directory\": \"<directory>\"')\ndef list_files(directory: str) -> list[str]:\n    \"\"\"lists files in a directory recursively\n\n    Args:\n        directory (str): The directory to search in\n\n    Returns:\n        list[str]: A list of files found in the directory\n    \"\"\"\n    found_files = []\n\n    for root, _, files in os.walk(directory):\n        for file in files:\n            if file.startswith(\".\"):\n                continue\n            relative_path = os.path.relpath(\n                os.path.join(root, file), CFG.workspace_path\n            )\n            found_files.append(relative_path)\n\n    return found_files\n\n\n@command(\n    \"download_file\",\n    \"Download File\",\n    '\"url\": \"<url>\", \"filename\": \"<filename>\"',\n    CFG.allow_downloads,\n    \"错误: 你没有下载到本地的权限.\",\n)\ndef download_file(url, filename):\n    \"\"\"Downloads a file\n    Args:\n        url (str): URL of the file to download\n        filename (str): Filename to save the file as\n    \"\"\"\n    try:\n        directory = os.path.dirname(filename)\n        os.makedirs(directory, exist_ok=True)\n        message = f\"{Fore.YELLOW}Downloading file from {Back.LIGHTBLUE_EX}{url}{Back.RESET}{Fore.RESET}\"\n        with Spinner(message) as spinner:\n            session = requests.Session()\n            retry = Retry(total=3, backoff_factor=1, status_forcelist=[502, 503, 504])\n            adapter = HTTPAdapter(max_retries=retry)\n            session.mount(\"http://\", adapter)\n            session.mount(\"https://\", adapter)\n\n            total_size = 0\n            downloaded_size = 0\n\n            with session.get(url, allow_redirects=True, stream=True) as r:\n                r.raise_for_status()\n                total_size = int(r.headers.get(\"Content-Length\", 0))\n                downloaded_size = 0\n\n                with open(filename, \"wb\") as f:\n                    for chunk in r.iter_content(chunk_size=8192):\n                        f.write(chunk)\n                        downloaded_size += len(chunk)\n\n                        # Update the progress message\n                        progress = f\"{readable_file_size(downloaded_size)} / {readable_file_size(total_size)}\"\n                        spinner.update_message(f\"{message} {progress}\")\n\n            return f'文件下载到本地成功，文件名: \"{filename}\"! (Size: {readable_file_size(downloaded_size)})'\n    except requests.HTTPError as err:\n        return f\"文件下载过程中遇到HTTP错误: {err}\"\n    except Exception as err:\n        return f\"错误: {err}\"\n"
  },
  {
    "path": "autogpt/commands/git_operations.py",
    "content": "\"\"\"Git operations for autogpt\"\"\"\nfrom git.repo import Repo\n\nfrom autogpt.commands.command import command\nfrom autogpt.config import Config\nfrom autogpt.url_utils.validators import validate_url\n\nCFG = Config()\n\n\n@command(\n    \"clone_repository\",\n    \"Clone Repository\",\n    '\"url\": \"<repository_url>\", \"clone_path\": \"<clone_path>\"',\n    CFG.github_username and CFG.github_api_key,\n    \"配置 github_username 和 github_api_key.\",\n)\n@validate_url\ndef clone_repository(url: str, clone_path: str) -> str:\n    \"\"\"Clone a GitHub repository locally.\n\n    Args:\n        url (str): The URL of the repository to clone.\n        clone_path (str): The path to clone the repository to.\n\n    Returns:\n        str: The result of the clone operation.\n    \"\"\"\n    split_url = url.split(\"//\")\n    auth_repo_url = f\"//{CFG.github_username}:{CFG.github_api_key}@\".join(split_url)\n    try:\n        Repo.clone_from(url=auth_repo_url, to_path=clone_path)\n        return f\"\"\"Cloned {url} to {clone_path}\"\"\"\n    except Exception as e:\n        return f\"错误: {str(e)}\"\n"
  },
  {
    "path": "autogpt/commands/google_search.py",
    "content": "\"\"\"Google search command for Autogpt.\"\"\"\nfrom __future__ import annotations\n\nimport json\n\nfrom duckduckgo_search import ddg\n\nfrom autogpt.commands.command import command\nfrom autogpt.config import Config\n\nCFG = Config()\n\n\n@command(\"google\", \"Google Search\", '\"query\": \"<query>\"', not CFG.google_api_key)\ndef google_search(query: str, num_results: int = 8) -> str:\n    \"\"\"Return the results of a Google search\n\n    Args:\n        query (str): The search query.\n        num_results (int): The number of results to return.\n\n    Returns:\n        str: The results of the search.\n    \"\"\"\n    search_results = []\n    if not query:\n        return json.dumps(search_results)\n\n    results = ddg(query, max_results=num_results)\n    if not results:\n        return json.dumps(search_results)\n\n    for j in results:\n        search_results.append(j)\n\n    results = json.dumps(search_results, ensure_ascii=False, indent=4)\n    return safe_google_results(results)\n\n\n@command(\n    \"google\",\n    \"Google Search\",\n    '\"query\": \"<query>\"',\n    bool(CFG.google_api_key),\n    \"配置 google_api_key.\",\n)\ndef google_official_search(query: str, num_results: int = 8) -> str | list[str]:\n    \"\"\"Return the results of a Google search using the official Google API\n\n    Args:\n        query (str): The search query.\n        num_results (int): The number of results to return.\n\n    Returns:\n        str: The results of the search.\n    \"\"\"\n\n    from googleapiclient.discovery import build\n    from googleapiclient.errors import HttpError\n\n    try:\n        # Get the Google API key and Custom Search Engine ID from the config file\n        api_key = CFG.google_api_key\n        custom_search_engine_id = CFG.custom_search_engine_id\n\n        # Initialize the Custom Search API service\n        service = build(\"customsearch\", \"v1\", developerKey=api_key)\n\n        # Send the search query and retrieve the results\n        result = (\n            service.cse()\n            .list(q=query, cx=custom_search_engine_id, num=num_results)\n            .execute()\n        )\n\n        # Extract the search result items from the response\n        search_results = result.get(\"items\", [])\n\n        # Create a list of only the URLs from the search results\n        search_results_links = [item[\"link\"] for item in search_results]\n\n    except HttpError as e:\n        # Handle errors in the API call\n        error_details = json.loads(e.content.decode())\n\n        # Check if the error is related to an invalid or missing API key\n        if error_details.get(\"error\", {}).get(\n            \"code\"\n        ) == 403 and \"invalid API key\" in error_details.get(\"error\", {}).get(\n            \"message\", \"\"\n        ):\n            return \"错误: 你提供的Google API key是错误的或者缺失.\"\n        else:\n            return f\"错误: {e}\"\n    # google_result can be a list or a string depending on the search results\n\n    # Return the list of search result URLs\n    return safe_google_results(search_results_links)\n\n\ndef safe_google_results(results: str | list) -> str:\n    \"\"\"\n        Return the results of a google search in a safe format.\n\n    Args:\n        results (str | list): The search results.\n\n    Returns:\n        str: The results of the search.\n    \"\"\"\n    if isinstance(results, list):\n        safe_message = json.dumps(\n            [result.encode(\"utf-8\", \"ignore\") for result in results]\n        )\n    else:\n        safe_message = results.encode(\"utf-8\", \"ignore\").decode(\"utf-8\")\n    return safe_message\n"
  },
  {
    "path": "autogpt/commands/image_gen.py",
    "content": "\"\"\" Image Generation Module for AutoGPT.\"\"\"\nimport io\nimport uuid\nfrom base64 import b64decode\n\nimport openai\nimport requests\nfrom PIL import Image\n\nfrom autogpt.commands.command import command\nfrom autogpt.config import Config\nfrom autogpt.logs import logger\n\nCFG = Config()\n\n\n@command(\"generate_image\", \"Generate Image\", '\"prompt\": \"<prompt>\"', CFG.image_provider)\ndef generate_image(prompt: str, size: int = 256) -> str:\n    \"\"\"Generate an image from a prompt.\n\n    Args:\n        prompt (str): The prompt to use\n        size (int, optional): The size of the image. Defaults to 256. (Not supported by HuggingFace)\n\n    Returns:\n        str: The filename of the image\n    \"\"\"\n    filename = f\"{CFG.workspace_path}/{str(uuid.uuid4())}.jpg\"\n\n    # DALL-E\n    if CFG.image_provider == \"dalle\":\n        return generate_image_with_dalle(prompt, filename, size)\n    # HuggingFace\n    elif CFG.image_provider == \"huggingface\":\n        return generate_image_with_hf(prompt, filename)\n    # SD WebUI\n    elif CFG.image_provider == \"sdwebui\":\n        return generate_image_with_sd_webui(prompt, filename, size)\n    return \"没有配置图片功能\"\n\n\ndef generate_image_with_hf(prompt: str, filename: str) -> str:\n    \"\"\"Generate an image with HuggingFace's API.\n\n    Args:\n        prompt (str): The prompt to use\n        filename (str): The filename to save the image to\n\n    Returns:\n        str: The filename of the image\n    \"\"\"\n    API_URL = (\n        f\"https://api-inference.huggingface.co/models/{CFG.huggingface_image_model}\"\n    )\n    if CFG.huggingface_api_token is None:\n        raise ValueError(\n            \"你需要再配置文件中配置Hugging Face API token.\"\n        )\n    headers = {\n        \"Authorization\": f\"Bearer {CFG.huggingface_api_token}\",\n        \"X-Use-Cache\": \"false\",\n    }\n\n    response = requests.post(\n        API_URL,\n        headers=headers,\n        json={\n            \"inputs\": prompt,\n        },\n    )\n\n    image = Image.open(io.BytesIO(response.content))\n    logger.info(f\"图片生成基于下面prompt:{prompt}\")\n\n    image.save(filename)\n\n    return f\"Saved to disk:{filename}\"\n\n\ndef generate_image_with_dalle(prompt: str, filename: str, size: int) -> str:\n    \"\"\"Generate an image with DALL-E.\n\n    Args:\n        prompt (str): The prompt to use\n        filename (str): The filename to save the image to\n        size (int): The size of the image\n\n    Returns:\n        str: The filename of the image\n    \"\"\"\n\n    # Check for supported image sizes\n    if size not in [256, 512, 1024]:\n        closest = min([256, 512, 1024], key=lambda x: abs(x - size))\n        logger.info(\n            f\"DALL-E only supports image sizes of 256x256, 512x512, or 1024x1024. Setting to {closest}, was {size}.\"\n        )\n        size = closest\n\n    response = openai.Image.create(\n        prompt=prompt,\n        n=1,\n        size=f\"{size}x{size}\",\n        response_format=\"b64_json\",\n        api_key=CFG.openai_api_key,\n    )\n\n    logger.info(f\"图片生成基于下面prompt:{prompt}\")\n\n    image_data = b64decode(response[\"data\"][0][\"b64_json\"])\n\n    with open(filename, mode=\"wb\") as png:\n        png.write(image_data)\n\n    return f\"Saved to disk:{filename}\"\n\n\ndef generate_image_with_sd_webui(\n    prompt: str,\n    filename: str,\n    size: int = 512,\n    negative_prompt: str = \"\",\n    extra: dict = {},\n) -> str:\n    \"\"\"Generate an image with Stable Diffusion webui.\n    Args:\n        prompt (str): The prompt to use\n        filename (str): The filename to save the image to\n        size (int, optional): The size of the image. Defaults to 256.\n        negative_prompt (str, optional): The negative prompt to use. Defaults to \"\".\n        extra (dict, optional): Extra parameters to pass to the API. Defaults to {}.\n    Returns:\n        str: The filename of the image\n    \"\"\"\n    # Create a session and set the basic auth if needed\n    s = requests.Session()\n    if CFG.sd_webui_auth:\n        username, password = CFG.sd_webui_auth.split(\":\")\n        s.auth = (username, password or \"\")\n\n    # Generate the images\n    response = requests.post(\n        f\"{CFG.sd_webui_url}/sdapi/v1/txt2img\",\n        json={\n            \"prompt\": prompt,\n            \"negative_prompt\": negative_prompt,\n            \"sampler_index\": \"DDIM\",\n            \"steps\": 20,\n            \"cfg_scale\": 7.0,\n            \"width\": size,\n            \"height\": size,\n            \"n_iter\": 1,\n            **extra,\n        },\n    )\n\n    logger.info(f\"图片生成基于下面prompt:{prompt}\")\n\n    # Save the image to disk\n    response = response.json()\n    b64 = b64decode(response[\"images\"][0].split(\",\", 1)[0])\n    image = Image.open(io.BytesIO(b64))\n    image.save(filename)\n\n    return f\"Saved to disk:{filename}\"\n"
  },
  {
    "path": "autogpt/commands/improve_code.py",
    "content": "from __future__ import annotations\n\nimport json\n\nfrom autogpt.commands.command import command\nfrom autogpt.llm import call_ai_function\n\n\n@command(\n    \"improve_code\",\n    \"获取优化代码\",\n    '\"suggestions\": \"<list_of_suggestions>\", \"code\": \"<full_code_string>\"',\n)\ndef improve_code(suggestions: list[str], code: str) -> str:\n    \"\"\"\n    A function that takes in code and suggestions and returns a response from create\n      chat completion api call.\n\n    Parameters:\n        suggestions (list): A list of suggestions around what needs to be improved.\n        code (str): Code to be improved.\n    Returns:\n        A result string from create chat completion. Improved code in response.\n    \"\"\"\n\n    function_string = (\n        \"def generate_improved_code(suggestions: list[str], code: str) -> str:\"\n    )\n    args = [json.dumps(suggestions), code]\n    description_string = (\n        \"基于优化建议提供优化后的代码，不要做其他修改.\"\n    )\n\n    return call_ai_function(function_string, args, description_string)\n"
  },
  {
    "path": "autogpt/commands/task_statuses.py",
    "content": "\"\"\"Task Statuses module.\"\"\"\nfrom __future__ import annotations\n\nfrom typing import NoReturn\n\nfrom autogpt.commands.command import command\nfrom autogpt.logs import logger\n\n\n@command(\n    \"task_complete\",\n    \"Task Complete (Shutdown)\",\n    '\"reason\": \"<reason>\"',\n)\ndef task_complete(reason: str) -> NoReturn:\n    \"\"\"\n    A function that takes in a string and exits the program\n\n    Parameters:\n        reason (str): The reason for shutting down.\n    Returns:\n        A result string from create chat completion. A list of suggestions to\n            improve the code.\n    \"\"\"\n    logger.info(title=\"关闭中...\\n\", message=reason)\n    quit()\n"
  },
  {
    "path": "autogpt/commands/times.py",
    "content": "from datetime import datetime\n\n\ndef get_datetime() -> str:\n    \"\"\"Return the current date and time\n\n    Returns:\n        str: The current date and time\n    \"\"\"\n    return \"当前日期与时间: \" + datetime.now().strftime(\"%Y-%m-%d %H:%M:%S\")\n"
  },
  {
    "path": "autogpt/commands/twitter.py",
    "content": "\"\"\"A module that contains a command to send a tweet.\"\"\"\nimport os\n\nimport tweepy\n\nfrom autogpt.commands.command import command\n\n\n@command(\n    \"send_tweet\",\n    \"发Tweet\",\n    '\"tweet_text\": \"<tweet_text>\"',\n)\ndef send_tweet(tweet_text: str) -> str:\n    \"\"\"\n      A function that takes in a string and returns a response from create chat\n        completion api call.\n\n    Args:\n      tweet_text (str): Text to be tweeted.\n\n      Returns:\n          A result from sending the tweet.\n    \"\"\"\n    consumer_key = os.environ.get(\"TW_CONSUMER_KEY\")\n    consumer_secret = os.environ.get(\"TW_CONSUMER_SECRET\")\n    access_token = os.environ.get(\"TW_ACCESS_TOKEN\")\n    access_token_secret = os.environ.get(\"TW_ACCESS_TOKEN_SECRET\")\n    # Authenticate to Twitter\n    auth = tweepy.OAuthHandler(consumer_key, consumer_secret)\n    auth.set_access_token(access_token, access_token_secret)\n\n    # Create API object\n    api = tweepy.API(auth)\n\n    # Send tweet\n    try:\n        api.update_status(tweet_text)\n        return \"Tweet发送成功!\"\n    except tweepy.TweepyException as e:\n        return f\"发送tweet错误: {e.reason}\"\n"
  },
  {
    "path": "autogpt/commands/web_playwright.py",
    "content": "\"\"\"Web scraping commands using Playwright\"\"\"\nfrom __future__ import annotations\n\nfrom autogpt.logs import logger\n\ntry:\n    from playwright.sync_api import sync_playwright\nexcept ImportError:\n    logger.info(\n        \"Playwright not installed. Please install it with 'pip install playwright' to use.\"\n    )\nfrom bs4 import BeautifulSoup\n\nfrom autogpt.processing.html import extract_hyperlinks, format_hyperlinks\n\n\ndef scrape_text(url: str) -> str:\n    \"\"\"Scrape text from a webpage\n\n    Args:\n        url (str): The URL to scrape text from\n\n    Returns:\n        str: The scraped text\n    \"\"\"\n    with sync_playwright() as p:\n        browser = p.chromium.launch()\n        page = browser.new_page()\n\n        try:\n            page.goto(url)\n            html_content = page.content()\n            soup = BeautifulSoup(html_content, \"html.parser\")\n\n            for script in soup([\"script\", \"style\"]):\n                script.extract()\n\n            text = soup.get_text()\n            lines = (line.strip() for line in text.splitlines())\n            chunks = (phrase.strip() for line in lines for phrase in line.split(\"  \"))\n            text = \"\\n\".join(chunk for chunk in chunks if chunk)\n\n        except Exception as e:\n            text = f\"Error: {str(e)}\"\n\n        finally:\n            browser.close()\n\n    return text\n\n\ndef scrape_links(url: str) -> str | list[str]:\n    \"\"\"Scrape links from a webpage\n\n    Args:\n        url (str): The URL to scrape links from\n\n    Returns:\n        Union[str, List[str]]: The scraped links\n    \"\"\"\n    with sync_playwright() as p:\n        browser = p.chromium.launch()\n        page = browser.new_page()\n\n        try:\n            page.goto(url)\n            html_content = page.content()\n            soup = BeautifulSoup(html_content, \"html.parser\")\n\n            for script in soup([\"script\", \"style\"]):\n                script.extract()\n\n            hyperlinks = extract_hyperlinks(soup, url)\n            formatted_links = format_hyperlinks(hyperlinks)\n\n        except Exception as e:\n            formatted_links = f\"Error: {str(e)}\"\n\n        finally:\n            browser.close()\n\n    return formatted_links\n"
  },
  {
    "path": "autogpt/commands/web_requests.py",
    "content": "\"\"\"Browse a webpage and summarize it using the LLM model\"\"\"\nfrom __future__ import annotations\n\nimport requests\nfrom bs4 import BeautifulSoup\nfrom requests import Response\n\nfrom autogpt.config import Config\nfrom autogpt.processing.html import extract_hyperlinks, format_hyperlinks\nfrom autogpt.url_utils.validators import validate_url\n\nCFG = Config()\n\nsession = requests.Session()\nsession.headers.update({\"User-Agent\": CFG.user_agent})\n\n\n@validate_url\ndef get_response(\n    url: str, timeout: int = 10\n) -> tuple[None, str] | tuple[Response, None]:\n    \"\"\"Get the response from a URL\n\n    Args:\n        url (str): The URL to get the response from\n        timeout (int): The timeout for the HTTP request\n\n    Returns:\n        tuple[None, str] | tuple[Response, None]: The response and error message\n\n    Raises:\n        ValueError: If the URL is invalid\n        requests.exceptions.RequestException: If the HTTP request fails\n    \"\"\"\n    try:\n        response = session.get(url, timeout=timeout)\n\n        # Check if the response contains an HTTP error\n        if response.status_code >= 400:\n            return None, f\"Error: HTTP {str(response.status_code)} error\"\n\n        return response, None\n    except ValueError as ve:\n        # Handle invalid URL format\n        return None, f\"Error: {str(ve)}\"\n\n    except requests.exceptions.RequestException as re:\n        # Handle exceptions related to the HTTP request\n        #  (e.g., connection errors, timeouts, etc.)\n        return None, f\"Error: {str(re)}\"\n\n\ndef scrape_text(url: str) -> str:\n    \"\"\"Scrape text from a webpage\n\n    Args:\n        url (str): The URL to scrape text from\n\n    Returns:\n        str: The scraped text\n    \"\"\"\n    response, error_message = get_response(url)\n    if error_message:\n        return error_message\n    if not response:\n        return \"Error: Could not get response\"\n\n    soup = BeautifulSoup(response.text, \"html.parser\")\n\n    for script in soup([\"script\", \"style\"]):\n        script.extract()\n\n    text = soup.get_text()\n    lines = (line.strip() for line in text.splitlines())\n    chunks = (phrase.strip() for line in lines for phrase in line.split(\"  \"))\n    text = \"\\n\".join(chunk for chunk in chunks if chunk)\n\n    return text\n\n\ndef scrape_links(url: str) -> str | list[str]:\n    \"\"\"Scrape links from a webpage\n\n    Args:\n        url (str): The URL to scrape links from\n\n    Returns:\n       str | list[str]: The scraped links\n    \"\"\"\n    response, error_message = get_response(url)\n    if error_message:\n        return error_message\n    if not response:\n        return \"Error: Could not get response\"\n    soup = BeautifulSoup(response.text, \"html.parser\")\n\n    for script in soup([\"script\", \"style\"]):\n        script.extract()\n\n    hyperlinks = extract_hyperlinks(soup, url)\n\n    return format_hyperlinks(hyperlinks)\n\n\ndef create_message(chunk, question):\n    \"\"\"Create a message for the user to summarize a chunk of text\"\"\"\n    return {\n        \"role\": \"user\",\n        \"content\": f'\"\"\"{chunk}\"\"\" Using the above text, answer the following'\n        f' question: \"{question}\" -- if the question cannot be answered using the'\n        \" text, summarize the text.\",\n    }\n"
  },
  {
    "path": "autogpt/commands/web_selenium.py",
    "content": "\"\"\"Selenium web scraping module.\"\"\"\nfrom __future__ import annotations\n\nimport logging\nfrom pathlib import Path\nfrom sys import platform\n\nfrom bs4 import BeautifulSoup\nfrom selenium import webdriver\nfrom selenium.common.exceptions import WebDriverException\nfrom selenium.webdriver.chrome.options import Options as ChromeOptions\nfrom selenium.webdriver.common.by import By\nfrom selenium.webdriver.firefox.options import Options as FirefoxOptions\nfrom selenium.webdriver.remote.webdriver import WebDriver\nfrom selenium.webdriver.safari.options import Options as SafariOptions\nfrom selenium.webdriver.support import expected_conditions as EC\nfrom selenium.webdriver.support.wait import WebDriverWait\nfrom webdriver_manager.chrome import ChromeDriverManager\nfrom webdriver_manager.firefox import GeckoDriverManager\n\nimport autogpt.processing.text as summary\nfrom autogpt.commands.command import command\nfrom autogpt.config import Config\nfrom autogpt.processing.html import extract_hyperlinks, format_hyperlinks\nfrom autogpt.url_utils.validators import validate_url\n\nFILE_DIR = Path(__file__).parent.parent\nCFG = Config()\n\n\n@command(\n    \"browse_website\",\n    \"浏览网页\",\n    '\"url\": \"<url>\", \"question\": \"<what_you_want_to_find_on_website>\"',\n)\n@validate_url\ndef browse_website(url: str, question: str) -> tuple[str, WebDriver]:\n    \"\"\"Browse a website and return the answer and links to the user\n\n    Args:\n        url (str): The url of the website to browse\n        question (str): The question asked by the user\n\n    Returns:\n        Tuple[str, WebDriver]: The answer and links to the user and the webdriver\n    \"\"\"\n    try:\n        driver, text = scrape_text_with_selenium(url)\n    except WebDriverException as e:\n        # These errors are often quite long and include lots of context.\n        # Just grab the first line.\n        msg = e.msg.split(\"\\n\")[0]\n        return f\"Error: {msg}\", None\n\n    add_header(driver)\n    summary_text = summary.summarize_text(url, text, question, driver)\n    links = scrape_links_with_selenium(driver, url)\n\n    # Limit links to 5\n    if len(links) > 5:\n        links = links[:5]\n    close_browser(driver)\n    return f\"从网页中获取的回答: {summary_text} \\n \\n 链接: {links}\", driver\n\n\ndef scrape_text_with_selenium(url: str) -> tuple[WebDriver, str]:\n    \"\"\"Scrape text from a website using selenium\n\n    Args:\n        url (str): The url of the website to scrape\n\n    Returns:\n        Tuple[WebDriver, str]: The webdriver and the text scraped from the website\n    \"\"\"\n    logging.getLogger(\"selenium\").setLevel(logging.CRITICAL)\n\n    options_available = {\n        \"chrome\": ChromeOptions,\n        \"safari\": SafariOptions,\n        \"firefox\": FirefoxOptions,\n    }\n\n    options = options_available[CFG.selenium_web_browser]()\n    options.add_argument(\n        \"user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.5615.49 Safari/537.36\"\n    )\n\n    if CFG.selenium_web_browser == \"firefox\":\n        if CFG.selenium_headless:\n            options.headless = True\n            options.add_argument(\"--disable-gpu\")\n        driver = webdriver.Firefox(\n            executable_path=GeckoDriverManager().install(), options=options\n        )\n    elif CFG.selenium_web_browser == \"safari\":\n        # Requires a bit more setup on the users end\n        # See https://developer.apple.com/documentation/webkit/testing_with_webdriver_in_safari\n        driver = webdriver.Safari(options=options)\n    else:\n        if platform == \"linux\" or platform == \"linux2\":\n            options.add_argument(\"--disable-dev-shm-usage\")\n            options.add_argument(\"--remote-debugging-port=9222\")\n\n        options.add_argument(\"--no-sandbox\")\n        if CFG.selenium_headless:\n            options.add_argument(\"--headless=new\")\n            options.add_argument(\"--disable-gpu\")\n\n        chromium_driver_path = Path(\"/usr/bin/chromedriver\")\n\n        driver = webdriver.Chrome(\n            executable_path=chromium_driver_path\n            if chromium_driver_path.exists()\n            else ChromeDriverManager().install(),\n            options=options,\n        )\n    driver.get(url)\n\n    WebDriverWait(driver, 10).until(\n        EC.presence_of_element_located((By.TAG_NAME, \"body\"))\n    )\n\n    # Get the HTML content directly from the browser's DOM\n    page_source = driver.execute_script(\"return document.body.outerHTML;\")\n    soup = BeautifulSoup(page_source, \"html.parser\")\n\n    for script in soup([\"script\", \"style\"]):\n        script.extract()\n\n    text = soup.get_text()\n    lines = (line.strip() for line in text.splitlines())\n    chunks = (phrase.strip() for line in lines for phrase in line.split(\"  \"))\n    text = \"\\n\".join(chunk for chunk in chunks if chunk)\n    return driver, text\n\n\ndef scrape_links_with_selenium(driver: WebDriver, url: str) -> list[str]:\n    \"\"\"Scrape links from a website using selenium\n\n    Args:\n        driver (WebDriver): The webdriver to use to scrape the links\n\n    Returns:\n        List[str]: The links scraped from the website\n    \"\"\"\n    page_source = driver.page_source\n    soup = BeautifulSoup(page_source, \"html.parser\")\n\n    for script in soup([\"script\", \"style\"]):\n        script.extract()\n\n    hyperlinks = extract_hyperlinks(soup, url)\n\n    return format_hyperlinks(hyperlinks)\n\n\ndef close_browser(driver: WebDriver) -> None:\n    \"\"\"Close the browser\n\n    Args:\n        driver (WebDriver): The webdriver to close\n\n    Returns:\n        None\n    \"\"\"\n    driver.quit()\n\n\ndef add_header(driver: WebDriver) -> None:\n    \"\"\"Add a header to the website\n\n    Args:\n        driver (WebDriver): The webdriver to use to add the header\n\n    Returns:\n        None\n    \"\"\"\n    try:\n        with open(f\"{FILE_DIR}/js/overlay.js\", \"r\") as overlay_file:\n            overlay_script = overlay_file.read()\n        driver.execute_script(overlay_script)\n    except Exception as e:\n        print(f\"Error executing overlay.js: {e}\")\n"
  },
  {
    "path": "autogpt/commands/write_tests.py",
    "content": "\"\"\"A module that contains a function to generate test cases for the submitted code.\"\"\"\nfrom __future__ import annotations\n\nimport json\n\nfrom autogpt.commands.command import command\nfrom autogpt.llm import call_ai_function\n\n\n@command(\n    \"write_tests\",\n    \"写入测试\",\n    '\"code\": \"<full_code_string>\", \"focus\": \"<list_of_focus_areas>\"',\n)\ndef write_tests(code: str, focus: list[str]) -> str:\n    \"\"\"\n    A function that takes in code and focus topics and returns a response from create\n      chat completion api call.\n\n    Parameters:\n        focus (list): A list of suggestions around what needs to be improved.\n        code (str): Code for test cases to be generated against.\n    Returns:\n        A result string from create chat completion. Test cases for the submitted code\n          in response.\n    \"\"\"\n\n    function_string = (\n        \"def create_test_cases(code: str, focus: Optional[str] = None) -> str:\"\n    )\n    args = [code, json.dumps(focus)]\n    description_string = (\n        \"如果需要，为现有代码生成测试用例，重点关注特定领域。\"\n    )\n\n    return call_ai_function(function_string, args, description_string)\n"
  },
  {
    "path": "autogpt/config/__init__.py",
    "content": "\"\"\"\nThis module contains the configuration classes for AutoGPT.\n\"\"\"\nfrom autogpt.config.ai_config import AIConfig\nfrom autogpt.config.config import Config, check_openai_api_key\n\n__all__ = [\n    \"check_openai_api_key\",\n    \"AIConfig\",\n    \"Config\",\n]\n"
  },
  {
    "path": "autogpt/config/ai_config.py",
    "content": "# sourcery skip: do-not-use-staticmethod\n\"\"\"\nA module that contains the AIConfig class object that contains the configuration\n\"\"\"\nfrom __future__ import annotations\n\nimport os\nimport platform\nfrom pathlib import Path\nfrom typing import Any, Optional, Type\n\nimport distro\nimport yaml\n\nfrom autogpt.prompts.generator import PromptGenerator\n\n# Soon this will go in a folder where it remembers more stuff about the run(s)\nSAVE_FILE = str(Path(os.getcwd()) / \"ai_settings.yaml\")\n\n\nclass AIConfig:\n    \"\"\"\n    A class object that contains the configuration information for the AI\n\n    Attributes:\n        ai_name (str): The name of the AI.\n        ai_role (str): The description of the AI's role.\n        ai_goals (list): The list of objectives the AI is supposed to complete.\n        api_budget (float): The maximum dollar value for API calls (0.0 means infinite)\n    \"\"\"\n\n    def __init__(\n        self,\n        ai_name: str = \"\",\n        ai_role: str = \"\",\n        ai_goals: list | None = None,\n        api_budget: float = 0.0,\n    ) -> None:\n        \"\"\"\n        Initialize a class instance\n\n        Parameters:\n            ai_name (str): The name of the AI.\n            ai_role (str): The description of the AI's role.\n            ai_goals (list): The list of objectives the AI is supposed to complete.\n            api_budget (float): The maximum dollar value for API calls (0.0 means infinite)\n        Returns:\n            None\n        \"\"\"\n        if ai_goals is None:\n            ai_goals = []\n        self.ai_name = ai_name\n        self.ai_role = ai_role\n        self.ai_goals = ai_goals\n        self.api_budget = api_budget\n        self.prompt_generator = None\n        self.command_registry = None\n\n    @staticmethod\n    def load(config_file: str = SAVE_FILE) -> \"AIConfig\":\n        \"\"\"\n        Returns class object with parameters (ai_name, ai_role, ai_goals, api_budget) loaded from\n          yaml file if yaml file exists,\n        else returns class with no parameters.\n\n        Parameters:\n           config_file (int): The path to the config yaml file.\n             DEFAULT: \"../ai_settings.yaml\"\n\n        Returns:\n            cls (object): An instance of given cls object\n        \"\"\"\n\n        try:\n            with open(config_file, encoding=\"utf-8\") as file:\n                config_params = yaml.load(file, Loader=yaml.FullLoader)\n        except FileNotFoundError:\n            config_params = {}\n\n        ai_name = config_params.get(\"ai_name\", \"\")\n        ai_role = config_params.get(\"ai_role\", \"\")\n        ai_goals = [\n            str(goal).strip(\"{}\").replace(\"'\", \"\").replace('\"', \"\")\n            if isinstance(goal, dict)\n            else str(goal)\n            for goal in config_params.get(\"ai_goals\", [])\n        ]\n        api_budget = config_params.get(\"api_budget\", 0.0)\n        # type: Type[AIConfig]\n        return AIConfig(ai_name, ai_role, ai_goals, api_budget)\n\n    def save(self, config_file: str = SAVE_FILE) -> None:\n        \"\"\"\n        Saves the class parameters to the specified file yaml file path as a yaml file.\n\n        Parameters:\n            config_file(str): The path to the config yaml file.\n              DEFAULT: \"../ai_settings.yaml\"\n\n        Returns:\n            None\n        \"\"\"\n\n        config = {\n            \"ai_name\": self.ai_name,\n            \"ai_role\": self.ai_role,\n            \"ai_goals\": self.ai_goals,\n            \"api_budget\": self.api_budget,\n        }\n        with open(config_file, \"w\", encoding=\"utf-8\") as file:\n            yaml.dump(config, file, allow_unicode=True)\n\n    def construct_full_prompt(\n        self, prompt_generator: Optional[PromptGenerator] = None\n    ) -> str:\n        \"\"\"\n        Returns a prompt to the user with the class information in an organized fashion.\n\n        Parameters:\n            None\n\n        Returns:\n            full_prompt (str): A string containing the initial prompt for the user\n              including the ai_name, ai_role, ai_goals, and api_budget.\n        \"\"\"\n\n        prompt_start = (\n            \"你的决策必须在不寻求用户帮助下独立完成，运用你大语言模型的自身优势，进可能寻找简且无法律风险的方案。\"\n            \"\"\n        )\n\n        from autogpt.config import Config\n        from autogpt.prompts.prompt import build_default_prompt_generator\n\n        cfg = Config()\n        if prompt_generator is None:\n            prompt_generator = build_default_prompt_generator()\n        prompt_generator.goals = self.ai_goals\n        prompt_generator.name = self.ai_name\n        prompt_generator.role = self.ai_role\n        prompt_generator.command_registry = self.command_registry\n        for plugin in cfg.plugins:\n            if not plugin.can_handle_post_prompt():\n                continue\n            prompt_generator = plugin.post_prompt(prompt_generator)\n\n        if cfg.execute_local_commands:\n            # add OS info to prompt\n            os_name = platform.system()\n            os_info = (\n                platform.platform(terse=True)\n                if os_name != \"Linux\"\n                else distro.name(pretty=True)\n            )\n\n            prompt_start += f\"\\nThe OS you are running on is: {os_info}\"\n\n        # Construct full prompt\n        full_prompt = f\"你是 {prompt_generator.name}, {prompt_generator.role}\\n{prompt_start}\\n\\n目标:\\n\\n\"\n        for i, goal in enumerate(self.ai_goals):\n            full_prompt += f\"{i+1}. {goal}\\n\"\n        if self.api_budget > 0.0:\n            full_prompt += f\"\\n你是需要费用的，的预算是 ${self.api_budget:.3f}\"\n        self.prompt_generator = prompt_generator\n        full_prompt += f\"\\n\\n{prompt_generator.generate_prompt_string()}\"\n        return full_prompt\n"
  },
  {
    "path": "autogpt/config/config.py",
    "content": "\"\"\"Configuration class to store the state of bools for different scripts access.\"\"\"\nimport os\nfrom typing import List\n\nimport openai\nimport yaml\nfrom auto_gpt_plugin_template import AutoGPTPluginTemplate\nfrom colorama import Fore\n\nfrom autogpt.singleton import Singleton\n\n\nclass Config(metaclass=Singleton):\n    \"\"\"\n    Configuration class to store the state of bools for different scripts access.\n    \"\"\"\n\n    def __init__(self) -> None:\n        \"\"\"Initialize the Config class\"\"\"\n        self.workspace_path = None\n        self.file_logger_path = None\n\n        self.debug_mode = False\n        self.continuous_mode = False\n        self.continuous_limit = 0\n        self.speak_mode = False\n        self.skip_reprompt = False\n        self.allow_downloads = False\n        self.skip_news = False\n\n        self.authorise_key = os.getenv(\"AUTHORISE_COMMAND_KEY\", \"y\")\n        self.exit_key = os.getenv(\"EXIT_KEY\", \"n\")\n\n        disabled_command_categories = os.getenv(\"DISABLED_COMMAND_CATEGORIES\")\n        if disabled_command_categories:\n            self.disabled_command_categories = disabled_command_categories.split(\",\")\n        else:\n            self.disabled_command_categories = []\n\n        self.ai_settings_file = os.getenv(\"AI_SETTINGS_FILE\", \"ai_settings.yaml\")\n        self.fast_llm_model = os.getenv(\"FAST_LLM_MODEL\", \"gpt-3.5-turbo\")\n        self.smart_llm_model = os.getenv(\"SMART_LLM_MODEL\", \"gpt-4\")\n        self.fast_token_limit = int(os.getenv(\"FAST_TOKEN_LIMIT\", 4000))\n        self.smart_token_limit = int(os.getenv(\"SMART_TOKEN_LIMIT\", 8000))\n        self.embedding_model = os.getenv(\"EMBEDDING_MODEL\", \"text-embedding-ada-002\")\n        self.embedding_tokenizer = os.getenv(\"EMBEDDING_TOKENIZER\", \"cl100k_base\")\n        self.embedding_token_limit = int(os.getenv(\"EMBEDDING_TOKEN_LIMIT\", 8191))\n        self.browse_chunk_max_length = int(os.getenv(\"BROWSE_CHUNK_MAX_LENGTH\", 3000))\n        self.browse_spacy_language_model = os.getenv(\n            \"BROWSE_SPACY_LANGUAGE_MODEL\", \"en_core_web_sm\"\n        )\n\n        self.openai_api_key = os.getenv(\"OPENAI_API_KEY\")\n        self.temperature = float(os.getenv(\"TEMPERATURE\", \"0\"))\n        self.use_azure = os.getenv(\"USE_AZURE\") == \"True\"\n        self.execute_local_commands = (\n            os.getenv(\"EXECUTE_LOCAL_COMMANDS\", \"False\") == \"True\"\n        )\n        self.restrict_to_workspace = (\n            os.getenv(\"RESTRICT_TO_WORKSPACE\", \"True\") == \"True\"\n        )\n\n        if self.use_azure:\n            self.load_azure_config()\n            openai.api_type = self.openai_api_type\n            openai.api_base = self.openai_api_base\n            openai.api_version = self.openai_api_version\n\n        self.elevenlabs_api_key = os.getenv(\"ELEVENLABS_API_KEY\")\n        self.elevenlabs_voice_1_id = os.getenv(\"ELEVENLABS_VOICE_1_ID\")\n        self.elevenlabs_voice_2_id = os.getenv(\"ELEVENLABS_VOICE_2_ID\")\n\n        self.use_mac_os_tts = False\n        self.use_mac_os_tts = os.getenv(\"USE_MAC_OS_TTS\")\n\n        self.chat_messages_enabled = os.getenv(\"CHAT_MESSAGES_ENABLED\") == \"True\"\n\n        self.use_brian_tts = False\n        self.use_brian_tts = os.getenv(\"USE_BRIAN_TTS\")\n\n        self.github_api_key = os.getenv(\"GITHUB_API_KEY\")\n        self.github_username = os.getenv(\"GITHUB_USERNAME\")\n\n        self.google_api_key = os.getenv(\"GOOGLE_API_KEY\")\n        self.custom_search_engine_id = os.getenv(\"CUSTOM_SEARCH_ENGINE_ID\")\n\n        self.pinecone_api_key = os.getenv(\"PINECONE_API_KEY\")\n        self.pinecone_region = os.getenv(\"PINECONE_ENV\")\n\n        self.weaviate_host = os.getenv(\"WEAVIATE_HOST\")\n        self.weaviate_port = os.getenv(\"WEAVIATE_PORT\")\n        self.weaviate_protocol = os.getenv(\"WEAVIATE_PROTOCOL\", \"http\")\n        self.weaviate_username = os.getenv(\"WEAVIATE_USERNAME\", None)\n        self.weaviate_password = os.getenv(\"WEAVIATE_PASSWORD\", None)\n        self.weaviate_scopes = os.getenv(\"WEAVIATE_SCOPES\", None)\n        self.weaviate_embedded_path = os.getenv(\"WEAVIATE_EMBEDDED_PATH\")\n        self.weaviate_api_key = os.getenv(\"WEAVIATE_API_KEY\", None)\n        self.use_weaviate_embedded = (\n            os.getenv(\"USE_WEAVIATE_EMBEDDED\", \"False\") == \"True\"\n        )\n\n        # milvus or zilliz cloud configuration.\n        self.milvus_addr = os.getenv(\"MILVUS_ADDR\", \"localhost:19530\")\n        self.milvus_username = os.getenv(\"MILVUS_USERNAME\")\n        self.milvus_password = os.getenv(\"MILVUS_PASSWORD\")\n        self.milvus_collection = os.getenv(\"MILVUS_COLLECTION\", \"autogpt\")\n        self.milvus_secure = os.getenv(\"MILVUS_SECURE\") == \"True\"\n\n        self.image_provider = os.getenv(\"IMAGE_PROVIDER\")\n        self.image_size = int(os.getenv(\"IMAGE_SIZE\", 256))\n        self.huggingface_api_token = os.getenv(\"HUGGINGFACE_API_TOKEN\")\n        self.huggingface_image_model = os.getenv(\n            \"HUGGINGFACE_IMAGE_MODEL\", \"CompVis/stable-diffusion-v1-4\"\n        )\n        self.huggingface_audio_to_text_model = os.getenv(\n            \"HUGGINGFACE_AUDIO_TO_TEXT_MODEL\"\n        )\n        self.sd_webui_url = os.getenv(\"SD_WEBUI_URL\", \"http://localhost:7860\")\n        self.sd_webui_auth = os.getenv(\"SD_WEBUI_AUTH\")\n\n        # Selenium browser settings\n        self.selenium_web_browser = os.getenv(\"USE_WEB_BROWSER\", \"chrome\")\n        self.selenium_headless = os.getenv(\"HEADLESS_BROWSER\", \"True\") == \"True\"\n\n        # User agent header to use when making HTTP requests\n        # Some websites might just completely deny request with an error code if\n        # no user agent was found.\n        self.user_agent = os.getenv(\n            \"USER_AGENT\",\n            \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36\"\n            \" (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36\",\n        )\n\n        self.redis_host = os.getenv(\"REDIS_HOST\", \"localhost\")\n        self.redis_port = os.getenv(\"REDIS_PORT\", \"6379\")\n        self.redis_password = os.getenv(\"REDIS_PASSWORD\", \"\")\n        self.wipe_redis_on_start = os.getenv(\"WIPE_REDIS_ON_START\", \"True\") == \"True\"\n        self.memory_index = os.getenv(\"MEMORY_INDEX\", \"auto-gpt\")\n        # Note that indexes must be created on db 0 in redis, this is not configurable.\n\n        self.memory_backend = os.getenv(\"MEMORY_BACKEND\", \"local\")\n\n        self.plugins_dir = os.getenv(\"PLUGINS_DIR\", \"plugins\")\n        self.plugins: List[AutoGPTPluginTemplate] = []\n        self.plugins_openai = []\n\n        plugins_allowlist = os.getenv(\"ALLOWLISTED_PLUGINS\")\n        if plugins_allowlist:\n            self.plugins_allowlist = plugins_allowlist.split(\",\")\n        else:\n            self.plugins_allowlist = []\n\n        plugins_denylist = os.getenv(\"DENYLISTED_PLUGINS\")\n        if plugins_denylist:\n            self.plugins_denylist = plugins_denylist.split(\",\")\n        else:\n            self.plugins_denylist = []\n\n    def get_azure_deployment_id_for_model(self, model: str) -> str:\n        \"\"\"\n        Returns the relevant deployment id for the model specified.\n\n        Parameters:\n            model(str): The model to map to the deployment id.\n\n        Returns:\n            The matching deployment id if found, otherwise an empty string.\n        \"\"\"\n        if model == self.fast_llm_model:\n            return self.azure_model_to_deployment_id_map[\n                \"fast_llm_model_deployment_id\"\n            ]  # type: ignore\n        elif model == self.smart_llm_model:\n            return self.azure_model_to_deployment_id_map[\n                \"smart_llm_model_deployment_id\"\n            ]  # type: ignore\n        elif model == \"text-embedding-ada-002\":\n            return self.azure_model_to_deployment_id_map[\n                \"embedding_model_deployment_id\"\n            ]  # type: ignore\n        else:\n            return \"\"\n\n    AZURE_CONFIG_FILE = os.path.join(os.path.dirname(__file__), \"../..\", \"azure.yaml\")\n\n    def load_azure_config(self, config_file: str = AZURE_CONFIG_FILE) -> None:\n        \"\"\"\n        Loads the configuration parameters for Azure hosting from the specified file\n          path as a yaml file.\n\n        Parameters:\n            config_file(str): The path to the config yaml file. DEFAULT: \"../azure.yaml\"\n\n        Returns:\n            None\n        \"\"\"\n        with open(config_file) as file:\n            config_params = yaml.load(file, Loader=yaml.FullLoader)\n        self.openai_api_type = config_params.get(\"azure_api_type\") or \"azure\"\n        self.openai_api_base = config_params.get(\"azure_api_base\") or \"\"\n        self.openai_api_version = (\n            config_params.get(\"azure_api_version\") or \"2023-03-15-preview\"\n        )\n        self.azure_model_to_deployment_id_map = config_params.get(\"azure_model_map\", {})\n\n    def set_continuous_mode(self, value: bool) -> None:\n        \"\"\"Set the continuous mode value.\"\"\"\n        self.continuous_mode = value\n\n    def set_continuous_limit(self, value: int) -> None:\n        \"\"\"Set the continuous limit value.\"\"\"\n        self.continuous_limit = value\n\n    def set_speak_mode(self, value: bool) -> None:\n        \"\"\"Set the speak mode value.\"\"\"\n        self.speak_mode = value\n\n    def set_fast_llm_model(self, value: str) -> None:\n        \"\"\"Set the fast LLM model value.\"\"\"\n        self.fast_llm_model = value\n\n    def set_smart_llm_model(self, value: str) -> None:\n        \"\"\"Set the smart LLM model value.\"\"\"\n        self.smart_llm_model = value\n\n    def set_fast_token_limit(self, value: int) -> None:\n        \"\"\"Set the fast token limit value.\"\"\"\n        self.fast_token_limit = value\n\n    def set_smart_token_limit(self, value: int) -> None:\n        \"\"\"Set the smart token limit value.\"\"\"\n        self.smart_token_limit = value\n\n    def set_embedding_model(self, value: str) -> None:\n        \"\"\"Set the model to use for creating embeddings.\"\"\"\n        self.embedding_model = value\n\n    def set_embedding_tokenizer(self, value: str) -> None:\n        \"\"\"Set the tokenizer to use when creating embeddings.\"\"\"\n        self.embedding_tokenizer = value\n\n    def set_embedding_token_limit(self, value: int) -> None:\n        \"\"\"Set the token limit for creating embeddings.\"\"\"\n        self.embedding_token_limit = value\n\n    def set_browse_chunk_max_length(self, value: int) -> None:\n        \"\"\"Set the browse_website command chunk max length value.\"\"\"\n        self.browse_chunk_max_length = value\n\n    def set_openai_api_key(self, value: str) -> None:\n        \"\"\"Set the OpenAI API key value.\"\"\"\n        self.openai_api_key = value\n\n    def set_elevenlabs_api_key(self, value: str) -> None:\n        \"\"\"Set the ElevenLabs API key value.\"\"\"\n        self.elevenlabs_api_key = value\n\n    def set_elevenlabs_voice_1_id(self, value: str) -> None:\n        \"\"\"Set the ElevenLabs Voice 1 ID value.\"\"\"\n        self.elevenlabs_voice_1_id = value\n\n    def set_elevenlabs_voice_2_id(self, value: str) -> None:\n        \"\"\"Set the ElevenLabs Voice 2 ID value.\"\"\"\n        self.elevenlabs_voice_2_id = value\n\n    def set_google_api_key(self, value: str) -> None:\n        \"\"\"Set the Google API key value.\"\"\"\n        self.google_api_key = value\n\n    def set_custom_search_engine_id(self, value: str) -> None:\n        \"\"\"Set the custom search engine id value.\"\"\"\n        self.custom_search_engine_id = value\n\n    def set_pinecone_api_key(self, value: str) -> None:\n        \"\"\"Set the Pinecone API key value.\"\"\"\n        self.pinecone_api_key = value\n\n    def set_pinecone_region(self, value: str) -> None:\n        \"\"\"Set the Pinecone region value.\"\"\"\n        self.pinecone_region = value\n\n    def set_debug_mode(self, value: bool) -> None:\n        \"\"\"Set the debug mode value.\"\"\"\n        self.debug_mode = value\n\n    def set_plugins(self, value: list) -> None:\n        \"\"\"Set the plugins value.\"\"\"\n        self.plugins = value\n\n    def set_temperature(self, value: int) -> None:\n        \"\"\"Set the temperature value.\"\"\"\n        self.temperature = value\n\n    def set_memory_backend(self, name: str) -> None:\n        \"\"\"Set the memory backend name.\"\"\"\n        self.memory_backend = name\n\n\ndef check_openai_api_key() -> None:\n    \"\"\"Check if the OpenAI API key is set in config.py or as an environment variable.\"\"\"\n    cfg = Config()\n    if not cfg.openai_api_key:\n        print(\n            Fore.RED\n            + \"请在.env文件中配置你的OpenAI API Key.\"\n            + Fore.RESET\n        )\n        print(\"你可以从这里获取你的key https://platform.openai.com/account/api-keys\")\n        exit(1)\n"
  },
  {
    "path": "autogpt/configurator.py",
    "content": "\"\"\"Configurator module.\"\"\"\nimport click\nfrom colorama import Back, Fore, Style\n\nfrom autogpt import utils\nfrom autogpt.config import Config\nfrom autogpt.logs import logger\nfrom autogpt.memory import get_supported_memory_backends\n\nCFG = Config()\n\n\ndef create_config(\n    continuous: bool,\n    continuous_limit: int,\n    ai_settings_file: str,\n    skip_reprompt: bool,\n    speak: bool,\n    debug: bool,\n    gpt3only: bool,\n    gpt4only: bool,\n    memory_type: str,\n    browser_name: str,\n    allow_downloads: bool,\n    skip_news: bool,\n) -> None:\n    \"\"\"Updates the config object with the given arguments.\n\n    Args:\n        continuous (bool): Whether to run in continuous mode\n        continuous_limit (int): The number of times to run in continuous mode\n        ai_settings_file (str): The path to the ai_settings.yaml file\n        skip_reprompt (bool): Whether to skip the re-prompting messages at the beginning of the script\n        speak (bool): Whether to enable speak mode\n        debug (bool): Whether to enable debug mode\n        gpt3only (bool): Whether to enable GPT3.5 only mode\n        gpt4only (bool): Whether to enable GPT4 only mode\n        memory_type (str): The type of memory backend to use\n        browser_name (str): The name of the browser to use when using selenium to scrape the web\n        allow_downloads (bool): Whether to allow Auto-GPT to download files natively\n        skips_news (bool): Whether to suppress the output of latest news on startup\n    \"\"\"\n    CFG.set_debug_mode(False)\n    CFG.set_continuous_mode(False)\n    CFG.set_speak_mode(False)\n\n    if debug:\n        logger.typewriter_log(\"Debug模式: \", Fore.GREEN, \"开启\")\n        CFG.set_debug_mode(True)\n\n    if continuous:\n        logger.typewriter_log(\"持续模式: \", Fore.RED, \"开启\")\n        logger.typewriter_log(\n            \"警告: \",\n            Fore.RED,\n            \"不推荐使用持续模式. 此模式存在风险，可能会让你的AI持续执行下去\"\n            \"并执行没有被你授权的指令动作\"\n            \"使用需谨慎，自负风险。\",\n        )\n        CFG.set_continuous_mode(True)\n\n        if continuous_limit:\n            logger.typewriter_log(\n                \"持续限额: \", Fore.GREEN, f\"{continuous_limit}\"\n            )\n            CFG.set_continuous_limit(continuous_limit)\n\n    # Check if continuous limit is used without continuous mode\n    if continuous_limit and not continuous:\n        raise click.UsageError(\"--continuous-limit can only be used with --continuous\")\n\n    if speak:\n        logger.typewriter_log(\"语音模式: \", Fore.GREEN, \"开启\")\n        CFG.set_speak_mode(True)\n\n    if gpt3only:\n        logger.typewriter_log(\"GPT3.5模式: \", Fore.GREEN, \"开启\")\n        CFG.set_smart_llm_model(CFG.fast_llm_model)\n\n    if gpt4only:\n        logger.typewriter_log(\"GPT4模式: \", Fore.GREEN, \"开启\")\n        CFG.set_fast_llm_model(CFG.smart_llm_model)\n\n    if memory_type:\n        supported_memory = get_supported_memory_backends()\n        chosen = memory_type\n        if chosen not in supported_memory:\n            logger.typewriter_log(\n                \"只支持一下记忆后台模式: \",\n                Fore.RED,\n                f\"{supported_memory}\",\n            )\n            logger.typewriter_log(\"默认至: \", Fore.YELLOW, CFG.memory_backend)\n        else:\n            CFG.memory_backend = chosen\n\n    if skip_reprompt:\n        logger.typewriter_log(\"跳过重新指令: \", Fore.GREEN, \"开启\")\n        CFG.skip_reprompt = True\n\n    if ai_settings_file:\n        file = ai_settings_file\n\n        # Validate file\n        (validated, message) = utils.validate_yaml_file(file)\n        if not validated:\n            logger.typewriter_log(\"文件校验失败\", Fore.RED, message)\n            logger.double_check()\n            exit(1)\n\n        logger.typewriter_log(\"使用AI配置文件:\", Fore.GREEN, file)\n        CFG.ai_settings_file = file\n        CFG.skip_reprompt = True\n\n    if browser_name:\n        CFG.selenium_web_browser = browser_name\n\n    if allow_downloads:\n        logger.typewriter_log(\"本地下载:\", Fore.GREEN, \"开启\")\n        logger.typewriter_log(\n            \"警告: \",\n            Fore.YELLOW,\n            f\"{Back.LIGHTYELLOW_EX}Auto-GPT将开启下载并存储文件至你的本地电脑中。{Back.RESET} \"\n            + \"建议您仔细监控它下载的任何文件。\",\n        )\n        logger.typewriter_log(\n            \"警告: \",\n            Fore.YELLOW,\n            f\"{Back.RED + Style.BRIGHT}请始终记住，永远不要打开您不确定的文件！{Style.RESET_ALL}\",\n        )\n        CFG.allow_downloads = True\n\n    if skip_news:\n        CFG.skip_news = True\n"
  },
  {
    "path": "autogpt/js/overlay.js",
    "content": "const overlay = document.createElement('div');\nObject.assign(overlay.style, {\n    position: 'fixed',\n    zIndex: 999999,\n    top: 0,\n    left: 0,\n    width: '100%',\n    height: '100%',\n    background: 'rgba(0, 0, 0, 0.7)',\n    color: '#fff',\n    fontSize: '24px',\n    fontWeight: 'bold',\n    display: 'flex',\n    justifyContent: 'center',\n    alignItems: 'center',\n});\nconst textContent = document.createElement('div');\nObject.assign(textContent.style, {\n    textAlign: 'center',\n});\ntextContent.textContent = 'AutoGPT Analyzing Page';\noverlay.appendChild(textContent);\ndocument.body.append(overlay);\ndocument.body.style.overflow = 'hidden';\nlet dotCount = 0;\nsetInterval(() => {\n    textContent.textContent = 'AutoGPT Analyzing Page' + '.'.repeat(dotCount);\n    dotCount = (dotCount + 1) % 4;\n}, 1000);\n"
  },
  {
    "path": "autogpt/json_utils/__init__.py",
    "content": ""
  },
  {
    "path": "autogpt/json_utils/json_fix_general.py",
    "content": "\"\"\"This module contains functions to fix JSON strings using general programmatic approaches, suitable for addressing\ncommon JSON formatting issues.\"\"\"\nfrom __future__ import annotations\n\nimport contextlib\nimport json\nimport re\nfrom typing import Optional\n\nfrom autogpt.config import Config\nfrom autogpt.json_utils.utilities import extract_char_position\nfrom autogpt.logs import logger\n\nCFG = Config()\n\n\ndef fix_invalid_escape(json_to_load: str, error_message: str) -> str:\n    \"\"\"Fix invalid escape sequences in JSON strings.\n\n    Args:\n        json_to_load (str): The JSON string.\n        error_message (str): The error message from the JSONDecodeError\n          exception.\n\n    Returns:\n        str: The JSON string with invalid escape sequences fixed.\n    \"\"\"\n    while error_message.startswith(\"Invalid \\\\escape\"):\n        bad_escape_location = extract_char_position(error_message)\n        json_to_load = (\n            json_to_load[:bad_escape_location] + json_to_load[bad_escape_location + 1 :]\n        )\n        try:\n            json.loads(json_to_load)\n            return json_to_load\n        except json.JSONDecodeError as e:\n            logger.debug(\"json loads error - fix invalid escape\", e)\n            error_message = str(e)\n    return json_to_load\n\n\ndef balance_braces(json_string: str) -> Optional[str]:\n    \"\"\"\n    Balance the braces in a JSON string.\n\n    Args:\n        json_string (str): The JSON string.\n\n    Returns:\n        str: The JSON string with braces balanced.\n    \"\"\"\n\n    open_braces_count = json_string.count(\"{\")\n    close_braces_count = json_string.count(\"}\")\n\n    while open_braces_count > close_braces_count:\n        json_string += \"}\"\n        close_braces_count += 1\n\n    while close_braces_count > open_braces_count:\n        json_string = json_string.rstrip(\"}\")\n        close_braces_count -= 1\n\n    with contextlib.suppress(json.JSONDecodeError):\n        json.loads(json_string)\n        return json_string\n\n\ndef add_quotes_to_property_names(json_string: str) -> str:\n    \"\"\"\n    Add quotes to property names in a JSON string.\n\n    Args:\n        json_string (str): The JSON string.\n\n    Returns:\n        str: The JSON string with quotes added to property names.\n    \"\"\"\n\n    def replace_func(match: re.Match) -> str:\n        return f'\"{match[1]}\":'\n\n    property_name_pattern = re.compile(r\"(\\w+):\")\n    corrected_json_string = property_name_pattern.sub(replace_func, json_string)\n\n    try:\n        json.loads(corrected_json_string)\n        return corrected_json_string\n    except json.JSONDecodeError as e:\n        raise e\n\n\ndef correct_json(json_to_load: str) -> str:\n    \"\"\"\n    Correct common JSON errors.\n    Args:\n        json_to_load (str): The JSON string.\n    \"\"\"\n\n    try:\n        logger.debug(\"json\", json_to_load)\n        json.loads(json_to_load)\n        return json_to_load\n    except json.JSONDecodeError as e:\n        logger.debug(\"json loads error\", e)\n        error_message = str(e)\n        if error_message.startswith(\"Invalid \\\\escape\"):\n            json_to_load = fix_invalid_escape(json_to_load, error_message)\n        if error_message.startswith(\n            \"Expecting property name enclosed in double quotes\"\n        ):\n            json_to_load = add_quotes_to_property_names(json_to_load)\n            try:\n                json.loads(json_to_load)\n                return json_to_load\n            except json.JSONDecodeError as e:\n                logger.debug(\"json loads error - add quotes\", e)\n                error_message = str(e)\n        if balanced_str := balance_braces(json_to_load):\n            return balanced_str\n    return json_to_load\n"
  },
  {
    "path": "autogpt/json_utils/json_fix_llm.py",
    "content": "\"\"\"This module contains functions to fix JSON strings generated by LLM models, such as ChatGPT, using the assistance\nof the ChatGPT API or LLM models.\"\"\"\nfrom __future__ import annotations\n\nimport contextlib\nimport json\nfrom typing import Any, Dict\n\nfrom colorama import Fore\nfrom regex import regex\n\nfrom autogpt.config import Config\nfrom autogpt.json_utils.json_fix_general import correct_json\nfrom autogpt.llm import call_ai_function\nfrom autogpt.logs import logger\nfrom autogpt.speech import say_text\n\nJSON_SCHEMA = \"\"\"\n{\n    \"command\": {\n        \"name\": \"command name\",\n        \"args\": {\n            \"arg name\": \"value\"\n        }\n    },\n    \"thoughts\":\n    {\n        \"text\": \"thought\",\n        \"reasoning\": \"reasoning\",\n        \"plan\": \"- short bulleted\\n- list that conveys\\n- long-term plan\",\n        \"criticism\": \"constructive self-criticism\",\n        \"speak\": \"thoughts summary to say to user\"\n    }\n}\n\"\"\"\n\nCFG = Config()\n\n\ndef auto_fix_json(json_string: str, schema: str) -> str:\n    \"\"\"Fix the given JSON string to make it parseable and fully compliant with\n        the provided schema using GPT-3.\n\n    Args:\n        json_string (str): The JSON string to fix.\n        schema (str): The schema to use to fix the JSON.\n    Returns:\n        str: The fixed JSON string.\n    \"\"\"\n    # Try to fix the JSON using GPT:\n    function_string = \"def fix_json(json_string: str, schema:str=None) -> str:\"\n    args = [f\"'''{json_string}'''\", f\"'''{schema}'''\"]\n    description_string = (\n        \"This function takes a JSON string and ensures that it\"\n        \" is parseable and fully compliant with the provided schema. If an object\"\n        \" or field specified in the schema isn't contained within the correct JSON,\"\n        \" it is omitted. The function also escapes any double quotes within JSON\"\n        \" string values to ensure that they are valid. If the JSON string contains\"\n        \" any None or NaN values, they are replaced with null before being parsed.\"\n    )\n\n    # If it doesn't already start with a \"`\", add one:\n    if not json_string.startswith(\"`\"):\n        json_string = \"```json\\n\" + json_string + \"\\n```\"\n    result_string = call_ai_function(\n        function_string, args, description_string, model=CFG.fast_llm_model\n    )\n    logger.debug(\"------------ JSON FIX ATTEMPT ---------------\")\n    logger.debug(f\"Original JSON: {json_string}\")\n    logger.debug(\"-----------\")\n    logger.debug(f\"Fixed JSON: {result_string}\")\n    logger.debug(\"----------- END OF FIX ATTEMPT ----------------\")\n\n    try:\n        json.loads(result_string)  # just check the validity\n        return result_string\n    except json.JSONDecodeError:  # noqa: E722\n        # Get the call stack:\n        # import traceback\n        # call_stack = traceback.format_exc()\n        # print(f\"Failed to fix JSON: '{json_string}' \"+call_stack)\n        return \"failed\"\n\n\ndef fix_json_using_multiple_techniques(assistant_reply: str) -> Dict[Any, Any]:\n    \"\"\"Fix the given JSON string to make it parseable and fully compliant with two techniques.\n\n    Args:\n        json_string (str): The JSON string to fix.\n\n    Returns:\n        str: The fixed JSON string.\n    \"\"\"\n    assistant_reply = assistant_reply.strip()\n    if assistant_reply.startswith(\"```json\"):\n        assistant_reply = assistant_reply[7:]\n    if assistant_reply.endswith(\"```\"):\n        assistant_reply = assistant_reply[:-3]\n    try:\n        return json.loads(assistant_reply)  # just check the validity\n    except json.JSONDecodeError:  # noqa: E722\n        pass\n\n    if assistant_reply.startswith(\"json \"):\n        assistant_reply = assistant_reply[5:]\n        assistant_reply = assistant_reply.strip()\n    try:\n        return json.loads(assistant_reply)  # just check the validity\n    except json.JSONDecodeError:  # noqa: E722\n        pass\n\n    # Parse and print Assistant response\n    assistant_reply_json = fix_and_parse_json(assistant_reply)\n    logger.debug(\"Assistant reply JSON: %s\", str(assistant_reply_json))\n    if assistant_reply_json == {}:\n        assistant_reply_json = attempt_to_fix_json_by_finding_outermost_brackets(\n            assistant_reply\n        )\n\n    logger.debug(\"Assistant reply JSON 2: %s\", str(assistant_reply_json))\n    if assistant_reply_json != {}:\n        return assistant_reply_json\n\n    logger.error(\n        \"Error: The following AI output couldn't be converted to a JSON:\\n\",\n        assistant_reply,\n    )\n    if CFG.speak_mode:\n        say_text(\"I have received an invalid JSON response from the OpenAI API.\")\n\n    return {}\n\n\ndef fix_and_parse_json(\n    json_to_load: str, try_to_fix_with_gpt: bool = True\n) -> Dict[Any, Any]:\n    \"\"\"Fix and parse JSON string\n\n    Args:\n        json_to_load (str): The JSON string.\n        try_to_fix_with_gpt (bool, optional): Try to fix the JSON with GPT.\n            Defaults to True.\n\n    Returns:\n        str or dict[Any, Any]: The parsed JSON.\n    \"\"\"\n\n    with contextlib.suppress(json.JSONDecodeError):\n        json_to_load = json_to_load.replace(\"\\t\", \"\")\n        return json.loads(json_to_load)\n\n    with contextlib.suppress(json.JSONDecodeError):\n        json_to_load = correct_json(json_to_load)\n        return json.loads(json_to_load)\n    # Let's do something manually:\n    # sometimes GPT responds with something BEFORE the braces:\n    # \"I'm sorry, I don't understand. Please try again.\"\n    # {\"text\": \"I'm sorry, I don't understand. Please try again.\",\n    #  \"confidence\": 0.0}\n    # So let's try to find the first brace and then parse the rest\n    #  of the string\n    try:\n        brace_index = json_to_load.index(\"{\")\n        maybe_fixed_json = json_to_load[brace_index:]\n        last_brace_index = maybe_fixed_json.rindex(\"}\")\n        maybe_fixed_json = maybe_fixed_json[: last_brace_index + 1]\n        return json.loads(maybe_fixed_json)\n    except (json.JSONDecodeError, ValueError) as e:\n        return try_ai_fix(try_to_fix_with_gpt, e, json_to_load)\n\n\ndef try_ai_fix(\n    try_to_fix_with_gpt: bool, exception: Exception, json_to_load: str\n) -> Dict[Any, Any]:\n    \"\"\"Try to fix the JSON with the AI\n\n    Args:\n        try_to_fix_with_gpt (bool): Whether to try to fix the JSON with the AI.\n        exception (Exception): The exception that was raised.\n        json_to_load (str): The JSON string to load.\n\n    Raises:\n        exception: If try_to_fix_with_gpt is False.\n\n    Returns:\n        str or dict[Any, Any]: The JSON string or dictionary.\n    \"\"\"\n    if not try_to_fix_with_gpt:\n        raise exception\n    if CFG.debug_mode:\n        logger.warn(\n            \"Warning: Failed to parse AI output, attempting to fix.\"\n            \"\\n If you see this warning frequently, it's likely that\"\n            \" your prompt is confusing the AI. Try changing it up\"\n            \" slightly.\"\n        )\n    # Now try to fix this up using the ai_functions\n    ai_fixed_json = auto_fix_json(json_to_load, JSON_SCHEMA)\n\n    if ai_fixed_json != \"failed\":\n        return json.loads(ai_fixed_json)\n    # This allows the AI to react to the error message,\n    #   which usually results in it correcting its ways.\n    # logger.error(\"Failed to fix AI output, telling the AI.\")\n    return {}\n\n\ndef attempt_to_fix_json_by_finding_outermost_brackets(json_string: str):\n    if CFG.speak_mode and CFG.debug_mode:\n        say_text(\n            \"I have received an invalid JSON response from the OpenAI API. \"\n            \"Trying to fix it now.\"\n        )\n        logger.error(\"Attempting to fix JSON by finding outermost brackets\\n\")\n\n    try:\n        json_pattern = regex.compile(r\"\\{(?:[^{}]|(?R))*\\}\")\n        json_match = json_pattern.search(json_string)\n\n        if json_match:\n            # Extract the valid JSON object from the string\n            json_string = json_match.group(0)\n            logger.typewriter_log(\n                title=\"Apparently json was fixed.\", title_color=Fore.GREEN\n            )\n            if CFG.speak_mode and CFG.debug_mode:\n                say_text(\"Apparently json was fixed.\")\n        else:\n            return {}\n\n    except (json.JSONDecodeError, ValueError):\n        if CFG.debug_mode:\n            logger.error(f\"Error: Invalid JSON: {json_string}\\n\")\n        if CFG.speak_mode:\n            say_text(\"Didn't work. I will have to ignore this response then.\")\n        logger.error(\"Error: Invalid JSON, setting it to empty JSON now.\\n\")\n        json_string = {}\n\n    return fix_and_parse_json(json_string)\n"
  },
  {
    "path": "autogpt/json_utils/llm_response_format_1.json",
    "content": "{\n    \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n    \"type\": \"object\",\n    \"properties\": {\n        \"thoughts\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"text\": {\"type\": \"string\"},\n                \"reasoning\": {\"type\": \"string\"},\n                \"plan\": {\"type\": \"string\"},\n                \"criticism\": {\"type\": \"string\"},\n                \"speak\": {\"type\": \"string\"}\n            },\n            \"required\": [\"text\", \"reasoning\", \"plan\", \"criticism\", \"speak\"],\n            \"additionalProperties\": false\n        },\n        \"command\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"name\": {\"type\": \"string\"},\n                \"args\": {\n                    \"type\": \"object\"\n                }\n            },\n            \"required\": [\"name\", \"args\"],\n            \"additionalProperties\": false\n        }\n    },\n    \"required\": [\"thoughts\", \"command\"],\n    \"additionalProperties\": false\n}\n"
  },
  {
    "path": "autogpt/json_utils/utilities.py",
    "content": "\"\"\"Utilities for the json_fixes package.\"\"\"\nimport json\nimport os.path\nimport re\n\nfrom jsonschema import Draft7Validator\n\nfrom autogpt.config import Config\nfrom autogpt.logs import logger\n\nCFG = Config()\nLLM_DEFAULT_RESPONSE_FORMAT = \"llm_response_format_1\"\n\n\ndef extract_char_position(error_message: str) -> int:\n    \"\"\"Extract the character position from the JSONDecodeError message.\n\n    Args:\n        error_message (str): The error message from the JSONDecodeError\n          exception.\n\n    Returns:\n        int: The character position.\n    \"\"\"\n\n    char_pattern = re.compile(r\"\\(char (\\d+)\\)\")\n    if match := char_pattern.search(error_message):\n        return int(match[1])\n    else:\n        raise ValueError(\"Character position not found in the error message.\")\n\n\ndef validate_json(json_object: object, schema_name: str) -> dict | None:\n    \"\"\"\n    :type schema_name: object\n    :param schema_name: str\n    :type json_object: object\n    \"\"\"\n    scheme_file = os.path.join(os.path.dirname(__file__), f\"{schema_name}.json\")\n    with open(scheme_file, \"r\") as f:\n        schema = json.load(f)\n    validator = Draft7Validator(schema)\n\n    if errors := sorted(validator.iter_errors(json_object), key=lambda e: e.path):\n        logger.error(\"The JSON object is invalid.\")\n        if CFG.debug_mode:\n            logger.error(\n                json.dumps(json_object, indent=4)\n            )  # Replace 'json_object' with the variable containing the JSON data\n            logger.error(\"The following issues were found:\")\n\n            for error in errors:\n                logger.error(f\"Error: {error.message}\")\n    else:\n        logger.debug(\"The JSON object is valid.\")\n\n    return json_object\n\n\ndef validate_json_string(json_string: str, schema_name: str) -> dict | None:\n    \"\"\"\n    :type schema_name: object\n    :param schema_name: str\n    :type json_object: object\n    \"\"\"\n\n    try:\n        json_loaded = json.loads(json_string)\n        return validate_json(json_loaded, schema_name)\n    except:\n        return None\n\n\ndef is_string_valid_json(json_string: str, schema_name: str) -> bool:\n    \"\"\"\n    :type schema_name: object\n    :param schema_name: str\n    :type json_object: object\n    \"\"\"\n\n    return validate_json_string(json_string, schema_name) is not None\n"
  },
  {
    "path": "autogpt/llm/__init__.py",
    "content": "from autogpt.llm.api_manager import ApiManager\nfrom autogpt.llm.base import (\n    ChatModelInfo,\n    ChatModelResponse,\n    EmbeddingModelInfo,\n    EmbeddingModelResponse,\n    LLMResponse,\n    Message,\n    ModelInfo,\n)\nfrom autogpt.llm.chat import chat_with_ai, create_chat_message, generate_context\nfrom autogpt.llm.llm_utils import (\n    call_ai_function,\n    chunked_tokens,\n    create_chat_completion,\n    get_ada_embedding,\n)\nfrom autogpt.llm.modelsinfo import COSTS\nfrom autogpt.llm.token_counter import count_message_tokens, count_string_tokens\n\n__all__ = [\n    \"ApiManager\",\n    \"Message\",\n    \"ModelInfo\",\n    \"ChatModelInfo\",\n    \"EmbeddingModelInfo\",\n    \"LLMResponse\",\n    \"ChatModelResponse\",\n    \"EmbeddingModelResponse\",\n    \"create_chat_message\",\n    \"generate_context\",\n    \"chat_with_ai\",\n    \"call_ai_function\",\n    \"create_chat_completion\",\n    \"get_ada_embedding\",\n    \"chunked_tokens\",\n    \"COSTS\",\n    \"count_message_tokens\",\n    \"count_string_tokens\",\n]\n"
  },
  {
    "path": "autogpt/llm/api_manager.py",
    "content": "from __future__ import annotations\n\nimport openai\n\nfrom autogpt.config import Config\nfrom autogpt.llm.modelsinfo import COSTS\nfrom autogpt.logs import logger\nfrom autogpt.singleton import Singleton\n\n\nclass ApiManager(metaclass=Singleton):\n    def __init__(self):\n        self.total_prompt_tokens = 0\n        self.total_completion_tokens = 0\n        self.total_cost = 0\n        self.total_budget = 0\n\n    def reset(self):\n        self.total_prompt_tokens = 0\n        self.total_completion_tokens = 0\n        self.total_cost = 0\n        self.total_budget = 0.0\n\n    def create_chat_completion(\n        self,\n        messages: list,  # type: ignore\n        model: str | None = None,\n        temperature: float = None,\n        max_tokens: int | None = None,\n        deployment_id=None,\n    ) -> str:\n        \"\"\"\n        Create a chat completion and update the cost.\n        Args:\n        messages (list): The list of messages to send to the API.\n        model (str): The model to use for the API call.\n        temperature (float): The temperature to use for the API call.\n        max_tokens (int): The maximum number of tokens for the API call.\n        Returns:\n        str: The AI's response.\n        \"\"\"\n        cfg = Config()\n        if temperature is None:\n            temperature = cfg.temperature\n        if deployment_id is not None:\n            response = openai.ChatCompletion.create(\n                deployment_id=deployment_id,\n                model=model,\n                messages=messages,\n                temperature=temperature,\n                max_tokens=max_tokens,\n                api_key=cfg.openai_api_key,\n            )\n        else:\n            response = openai.ChatCompletion.create(\n                model=model,\n                messages=messages,\n                temperature=temperature,\n                max_tokens=max_tokens,\n                api_key=cfg.openai_api_key,\n            )\n        logger.debug(f\"Response: {response}\")\n        prompt_tokens = response.usage.prompt_tokens\n        completion_tokens = response.usage.completion_tokens\n        self.update_cost(prompt_tokens, completion_tokens, model)\n        return response\n\n    def update_cost(self, prompt_tokens, completion_tokens, model):\n        \"\"\"\n        Update the total cost, prompt tokens, and completion tokens.\n\n        Args:\n        prompt_tokens (int): The number of tokens used in the prompt.\n        completion_tokens (int): The number of tokens used in the completion.\n        model (str): The model used for the API call.\n        \"\"\"\n        self.total_prompt_tokens += prompt_tokens\n        self.total_completion_tokens += completion_tokens\n        self.total_cost += (\n            prompt_tokens * COSTS[model][\"prompt\"]\n            + completion_tokens * COSTS[model][\"completion\"]\n        ) / 1000\n        logger.debug(f\"Total running cost: ${self.total_cost:.3f}\")\n\n    def set_total_budget(self, total_budget):\n        \"\"\"\n        Sets the total user-defined budget for API calls.\n\n        Args:\n        total_budget (float): The total budget for API calls.\n        \"\"\"\n        self.total_budget = total_budget\n\n    def get_total_prompt_tokens(self):\n        \"\"\"\n        Get the total number of prompt tokens.\n\n        Returns:\n        int: The total number of prompt tokens.\n        \"\"\"\n        return self.total_prompt_tokens\n\n    def get_total_completion_tokens(self):\n        \"\"\"\n        Get the total number of completion tokens.\n\n        Returns:\n        int: The total number of completion tokens.\n        \"\"\"\n        return self.total_completion_tokens\n\n    def get_total_cost(self):\n        \"\"\"\n        Get the total cost of API calls.\n\n        Returns:\n        float: The total cost of API calls.\n        \"\"\"\n        return self.total_cost\n\n    def get_total_budget(self):\n        \"\"\"\n        Get the total user-defined budget for API calls.\n\n        Returns:\n        float: The total budget for API calls.\n        \"\"\"\n        return self.total_budget\n"
  },
  {
    "path": "autogpt/llm/base.py",
    "content": "from dataclasses import dataclass, field\nfrom typing import List, TypedDict\n\n\nclass Message(TypedDict):\n    \"\"\"OpenAI Message object containing a role and the message content\"\"\"\n\n    role: str\n    content: str\n\n\n@dataclass\nclass ModelInfo:\n    \"\"\"Struct for model information.\n\n    Would be lovely to eventually get this directly from APIs, but needs to be scraped from\n    websites for now.\n\n    \"\"\"\n\n    name: str\n    prompt_token_cost: float\n    completion_token_cost: float\n    max_tokens: int\n\n\n@dataclass\nclass ChatModelInfo(ModelInfo):\n    \"\"\"Struct for chat model information.\"\"\"\n\n    pass\n\n\n@dataclass\nclass EmbeddingModelInfo(ModelInfo):\n    \"\"\"Struct for embedding model information.\"\"\"\n\n    embedding_dimensions: int\n\n\n@dataclass\nclass LLMResponse:\n    \"\"\"Standard response struct for a response from an LLM model.\"\"\"\n\n    model_info: ModelInfo\n    prompt_tokens_used: int = 0\n    completion_tokens_used: int = 0\n\n\n@dataclass\nclass EmbeddingModelResponse(LLMResponse):\n    \"\"\"Standard response struct for a response from an embedding model.\"\"\"\n\n    embedding: List[float] = field(default_factory=list)\n\n    def __post_init__(self):\n        if self.completion_tokens_used:\n            raise ValueError(\"Embeddings should not have completion tokens used.\")\n\n\n@dataclass\nclass ChatModelResponse(LLMResponse):\n    \"\"\"Standard response struct for a response from an LLM model.\"\"\"\n\n    content: str = None\n"
  },
  {
    "path": "autogpt/llm/chat.py",
    "content": "import time\nfrom random import shuffle\n\nfrom openai.error import RateLimitError\n\nfrom autogpt.config import Config\nfrom autogpt.llm.api_manager import ApiManager\nfrom autogpt.llm.base import Message\nfrom autogpt.llm.llm_utils import create_chat_completion\nfrom autogpt.llm.token_counter import count_message_tokens\nfrom autogpt.logs import logger\nfrom autogpt.memory_management.store_memory import (\n    save_memory_trimmed_from_context_window,\n)\nfrom autogpt.memory_management.summary_memory import (\n    get_newly_trimmed_messages,\n    update_running_summary,\n)\n\ncfg = Config()\n\n\ndef create_chat_message(role, content) -> Message:\n    \"\"\"\n    Create a chat message with the given role and content.\n\n    Args:\n    role (str): The role of the message sender, e.g., \"system\", \"user\", or \"assistant\".\n    content (str): The content of the message.\n\n    Returns:\n    dict: A dictionary containing the role and content of the message.\n    \"\"\"\n    return {\"role\": role, \"content\": content}\n\n\ndef generate_context(prompt, relevant_memory, full_message_history, model):\n    current_context = [\n        create_chat_message(\"system\", prompt),\n        create_chat_message(\n            \"system\", f\"当前的日期和时间是 {time.strftime('%c')}\"\n        ),\n        # create_chat_message(\n        #     \"system\",\n        #     f\"This reminds you of these events from your past:\\n{relevant_memory}\\n\\n\",\n        # ),\n    ]\n\n    # Add messages from the full message history until we reach the token limit\n    next_message_to_add_index = len(full_message_history) - 1\n    insertion_index = len(current_context)\n    # Count the currently used tokens\n    current_tokens_used = count_message_tokens(current_context, model)\n    return (\n        next_message_to_add_index,\n        current_tokens_used,\n        insertion_index,\n        current_context,\n    )\n\n\n# TODO: Change debug from hardcode to argument\ndef chat_with_ai(\n    agent, prompt, user_input, full_message_history, permanent_memory, token_limit\n):\n    \"\"\"Interact with the OpenAI API, sending the prompt, user input, message history,\n    and permanent memory.\"\"\"\n    while True:\n        try:\n            \"\"\"\n            Interact with the OpenAI API, sending the prompt, user input,\n                message history, and permanent memory.\n\n            Args:\n                prompt (str): The prompt explaining the rules to the AI.\n                user_input (str): The input from the user.\n                full_message_history (list): The list of all messages sent between the\n                    user and the AI.\n                permanent_memory (Obj): The memory object containing the permanent\n                  memory.\n                token_limit (int): The maximum number of tokens allowed in the API call.\n\n            Returns:\n            str: The AI's response.\n            \"\"\"\n            model = cfg.fast_llm_model  # TODO: Change model from hardcode to argument\n            # Reserve 1000 tokens for the response\n            logger.debug(f\"Token限额: {token_limit}\")\n            send_token_limit = token_limit - 1000\n\n            # if len(full_message_history) == 0:\n            #     relevant_memory = \"\"\n            # else:\n            #     recent_history = full_message_history[-5:]\n            #     shuffle(recent_history)\n            #     relevant_memories = permanent_memory.get_relevant(\n            #         str(recent_history), 5\n            #     )\n            #     if relevant_memories:\n            #         shuffle(relevant_memories)\n            #     relevant_memory = str(relevant_memories)\n            relevant_memory = \"\"\n            logger.debug(f\"Memory Stats: {permanent_memory.get_stats()}\")\n\n            (\n                next_message_to_add_index,\n                current_tokens_used,\n                insertion_index,\n                current_context,\n            ) = generate_context(prompt, relevant_memory, full_message_history, model)\n\n            # while current_tokens_used > 2500:\n            #     # remove memories until we are under 2500 tokens\n            #     relevant_memory = relevant_memory[:-1]\n            #     (\n            #         next_message_to_add_index,\n            #         current_tokens_used,\n            #         insertion_index,\n            #         current_context,\n            #     ) = generate_context(\n            #         prompt, relevant_memory, full_message_history, model\n            #     )\n\n            current_tokens_used += count_message_tokens(\n                [create_chat_message(\"user\", user_input)], model\n            )  # Account for user input (appended later)\n\n            current_tokens_used += 500  # Account for memory (appended later) TODO: The final memory may be less than 500 tokens\n\n            # Add Messages until the token limit is reached or there are no more messages to add.\n            while next_message_to_add_index >= 0:\n                # print (f\"CURRENT TOKENS USED: {current_tokens_used}\")\n                message_to_add = full_message_history[next_message_to_add_index]\n\n                tokens_to_add = count_message_tokens([message_to_add], model)\n                if current_tokens_used + tokens_to_add > send_token_limit:\n                    # save_memory_trimmed_from_context_window(\n                    #     full_message_history,\n                    #     next_message_to_add_index,\n                    #     permanent_memory,\n                    # )\n                    break\n\n                # Add the most recent message to the start of the current context,\n                #  after the two system prompts.\n                current_context.insert(\n                    insertion_index, full_message_history[next_message_to_add_index]\n                )\n\n                # Count the currently used tokens\n                current_tokens_used += tokens_to_add\n\n                # Move to the next most recent message in the full message history\n                next_message_to_add_index -= 1\n\n            # Insert Memories\n            if len(full_message_history) > 0:\n                (\n                    newly_trimmed_messages,\n                    agent.last_memory_index,\n                ) = get_newly_trimmed_messages(\n                    full_message_history=full_message_history,\n                    current_context=current_context,\n                    last_memory_index=agent.last_memory_index,\n                )\n                agent.summary_memory = update_running_summary(\n                    current_memory=agent.summary_memory,\n                    new_events=newly_trimmed_messages,\n                )\n                current_context.insert(insertion_index, agent.summary_memory)\n\n            api_manager = ApiManager()\n            # inform the AI about its remaining budget (if it has one)\n            if api_manager.get_total_budget() > 0.0:\n                remaining_budget = (\n                    api_manager.get_total_budget() - api_manager.get_total_cost()\n                )\n                if remaining_budget < 0:\n                    remaining_budget = 0\n                system_message = (\n                    f\"你的剩余API预算为 ${remaining_budget:.3f}\"\n                    + (\n                        \" 已超预算! 关闭!\\n\\n\"\n                        if remaining_budget == 0\n                        else \" 预算非常接近限额! 优雅关闭中!\\n\\n\"\n                        if remaining_budget < 0.005\n                        else \" 预算接近限额. 完成中.\\n\\n\"\n                        if remaining_budget < 0.01\n                        else \"\\n\\n\"\n                    )\n                )\n                logger.debug(system_message)\n                current_context.append(create_chat_message(\"system\", system_message))\n\n            # Append user input, the length of this is accounted for above\n            current_context.extend([create_chat_message(\"user\", user_input)])\n\n            plugin_count = len(cfg.plugins)\n            for i, plugin in enumerate(cfg.plugins):\n                if not plugin.can_handle_on_planning():\n                    continue\n                plugin_response = plugin.on_planning(\n                    agent.prompt_generator, current_context\n                )\n                if not plugin_response or plugin_response == \"\":\n                    continue\n                tokens_to_add = count_message_tokens(\n                    [create_chat_message(\"system\", plugin_response)], model\n                )\n                if current_tokens_used + tokens_to_add > send_token_limit:\n                    logger.debug(\"Plugin response too long, skipping:\", plugin_response)\n                    logger.debug(\"Plugins remaining at stop:\", plugin_count - i)\n                    break\n                current_context.append(create_chat_message(\"system\", plugin_response))\n\n            # Calculate remaining tokens\n            tokens_remaining = token_limit - current_tokens_used\n            # assert tokens_remaining >= 0, \"Tokens remaining is negative.\n            # This should never happen, please submit a bug report at\n            #  https://www.github.com/Torantulino/Auto-GPT\"\n\n            # Debug print the current context\n            logger.debug(f\"Token限额: {token_limit}\")\n            logger.debug(f\"发送Token数量: {current_tokens_used}\")\n            logger.debug(f\"回复剩余Token: {tokens_remaining}\")\n            logger.debug(\"------------ 内容发送至AI ---------------\")\n            for message in current_context:\n                # Skip printing the prompt\n                if message[\"role\"] == \"system\" and message[\"content\"] == prompt:\n                    continue\n                logger.debug(f\"{message['role'].capitalize()}: {message['content']}\")\n                logger.debug(\"\")\n            logger.debug(\"----------- 内容结束 ----------------\")\n\n            # TODO: use a model defined elsewhere, so that model can contain\n            # temperature and other settings we care about\n            assistant_reply = create_chat_completion(\n                model=model,\n                messages=current_context,\n                max_tokens=tokens_remaining,\n            )\n\n            # Update full message history\n            full_message_history.append(create_chat_message(\"user\", user_input))\n            full_message_history.append(\n                create_chat_message(\"assistant\", assistant_reply)\n            )\n\n            return assistant_reply\n        except RateLimitError:\n            # TODO: When we switch to langchain, this is built in\n            logger.warn(\"Error: \", \"API Rate Limit Reached. Waiting 10 seconds...\")\n            time.sleep(10)\n"
  },
  {
    "path": "autogpt/llm/llm_utils.py",
    "content": "from __future__ import annotations\n\nimport functools\nimport time\nfrom itertools import islice\nfrom typing import List, Optional\n\nimport numpy as np\nimport openai\nimport tiktoken\nfrom colorama import Fore, Style\nfrom openai.error import APIError, RateLimitError, Timeout\n\nfrom autogpt.config import Config\nfrom autogpt.llm.api_manager import ApiManager\nfrom autogpt.llm.base import Message\nfrom autogpt.logs import logger\n\n\ndef retry_openai_api(\n    num_retries: int = 10,\n    backoff_base: float = 2.0,\n    warn_user: bool = True,\n):\n    \"\"\"Retry an OpenAI API call.\n\n    Args:\n        num_retries int: Number of retries. Defaults to 10.\n        backoff_base float: Base for exponential backoff. Defaults to 2.\n        warn_user bool: Whether to warn the user. Defaults to True.\n    \"\"\"\n    retry_limit_msg = f\"{Fore.RED}Error: \" f\"Reached rate limit, passing...{Fore.RESET}\"\n    api_key_error_msg = (\n        f\"Please double check that you have setup a \"\n        f\"{Fore.CYAN + Style.BRIGHT}PAID{Style.RESET_ALL} OpenAI API Account. You can \"\n        f\"read more here: {Fore.CYAN}https://docs.agpt.co/setup/#getting-an-api-key{Fore.RESET}\"\n    )\n    backoff_msg = (\n        f\"{Fore.RED}Error: API Bad gateway. Waiting {{backoff}} seconds...{Fore.RESET}\"\n    )\n\n    def _wrapper(func):\n        @functools.wraps(func)\n        def _wrapped(*args, **kwargs):\n            user_warned = not warn_user\n            num_attempts = num_retries + 1  # +1 for the first attempt\n            for attempt in range(1, num_attempts + 1):\n                try:\n                    return func(*args, **kwargs)\n\n                except RateLimitError:\n                    if attempt == num_attempts:\n                        raise\n\n                    logger.debug(retry_limit_msg)\n                    if not user_warned:\n                        logger.double_check(api_key_error_msg)\n                        user_warned = True\n\n                except APIError as e:\n                    if (e.http_status != 502) or (attempt == num_attempts):\n                        raise\n\n                backoff = backoff_base ** (attempt + 2)\n                logger.debug(backoff_msg.format(backoff=backoff))\n                time.sleep(backoff)\n\n        return _wrapped\n\n    return _wrapper\n\n\ndef call_ai_function(\n    function: str, args: list, description: str, model: str | None = None\n) -> str:\n    \"\"\"Call an AI function\n\n    This is a magic function that can do anything with no-code. See\n    https://github.com/Torantulino/AI-Functions for more info.\n\n    Args:\n        function (str): The function to call\n        args (list): The arguments to pass to the function\n        description (str): The description of the function\n        model (str, optional): The model to use. Defaults to None.\n\n    Returns:\n        str: The response from the function\n    \"\"\"\n    cfg = Config()\n    if model is None:\n        model = cfg.smart_llm_model\n    # For each arg, if any are None, convert to \"None\":\n    args = [str(arg) if arg is not None else \"None\" for arg in args]\n    # parse args to comma separated string\n    args: str = \", \".join(args)\n    messages: List[Message] = [\n        {\n            \"role\": \"system\",\n            \"content\": f\"You are now the following python function: ```# {description}\"\n            f\"\\n{function}```\\n\\nOnly respond with your `return` value.\",\n        },\n        {\"role\": \"user\", \"content\": args},\n    ]\n\n    return create_chat_completion(model=model, messages=messages, temperature=0)\n\n\n# Overly simple abstraction until we create something better\n# simple retry mechanism when getting a rate error or a bad gateway\ndef create_chat_completion(\n    messages: List[Message],  # type: ignore\n    model: Optional[str] = None,\n    temperature: float = None,\n    max_tokens: Optional[int] = None,\n) -> str:\n    \"\"\"Create a chat completion using the OpenAI API\n\n    Args:\n        messages (List[Message]): The messages to send to the chat completion\n        model (str, optional): The model to use. Defaults to None.\n        temperature (float, optional): The temperature to use. Defaults to 0.9.\n        max_tokens (int, optional): The max tokens to use. Defaults to None.\n\n    Returns:\n        str: The response from the chat completion\n    \"\"\"\n    cfg = Config()\n    if temperature is None:\n        temperature = cfg.temperature\n\n    num_retries = 10\n    warned_user = False\n    logger.debug(\n        f\"{Fore.GREEN}Creating chat completion with model {model}, temperature {temperature}, max_tokens {max_tokens}{Fore.RESET}\"\n    )\n    for plugin in cfg.plugins:\n        if plugin.can_handle_chat_completion(\n            messages=messages,\n            model=model,\n            temperature=temperature,\n            max_tokens=max_tokens,\n        ):\n            message = plugin.handle_chat_completion(\n                messages=messages,\n                model=model,\n                temperature=temperature,\n                max_tokens=max_tokens,\n            )\n            if message is not None:\n                return message\n    api_manager = ApiManager()\n    response = None\n    for attempt in range(num_retries):\n        backoff = 2 ** (attempt + 2)\n        try:\n            if cfg.use_azure:\n                response = api_manager.create_chat_completion(\n                    deployment_id=cfg.get_azure_deployment_id_for_model(model),\n                    model=model,\n                    messages=messages,\n                    temperature=temperature,\n                    max_tokens=max_tokens,\n                )\n            else:\n                response = api_manager.create_chat_completion(\n                    model=model,\n                    messages=messages,\n                    temperature=temperature,\n                    max_tokens=max_tokens,\n                )\n            break\n        except RateLimitError:\n            logger.debug(\n                f\"{Fore.RED}Error: \", f\"到达请求限额, passing...{Fore.RESET}\"\n            )\n            if not warned_user:\n                logger.double_check(\n                    f\"请再次检查你已经配置好了一个 {Fore.CYAN + Style.BRIGHT}付费的{Style.RESET_ALL} OpenAI API账户. \"\n                    + f\"你可以从这里获取更多信息: {Fore.CYAN}https://docs.agpt.co/setup/#getting-an-api-key{Fore.RESET}\"\n                )\n                warned_user = True\n        except (APIError, Timeout) as e:\n            if e.http_status != 502:\n                raise\n            if attempt == num_retries - 1:\n                raise\n        logger.debug(\n            f\"{Fore.RED}Error: \",\n            f\"API Bad gateway. 等待 {backoff} 秒...{Fore.RESET}\",\n        )\n        time.sleep(backoff)\n    if response is None:\n        logger.typewriter_log(\n            \"从OPENAI获取信息失败\",\n            Fore.RED,\n            \"Auto-GPT从OpenAI服务中获取请求失败. \"\n            + f\"尝试重新启动Auto-GPT, 如果这个问题持续出现请增加后缀 `{Fore.CYAN}--debug{Fore.RESET}`.\",\n        )\n        logger.double_check()\n        if cfg.debug_mode:\n            raise RuntimeError(f\"请求 {num_retries} 次后失败\")\n        else:\n            quit(1)\n    resp = response.choices[0].message[\"content\"]\n    for plugin in cfg.plugins:\n        if not plugin.can_handle_on_response():\n            continue\n        resp = plugin.on_response(resp)\n    return resp\n\n\ndef batched(iterable, n):\n    \"\"\"Batch data into tuples of length n. The last batch may be shorter.\"\"\"\n    # batched('ABCDEFG', 3) --> ABC DEF G\n    if n < 1:\n        raise ValueError(\"n 必须为数字\")\n    it = iter(iterable)\n    while batch := tuple(islice(it, n)):\n        yield batch\n\n\ndef chunked_tokens(text, tokenizer_name, chunk_length):\n    tokenizer = tiktoken.get_encoding(tokenizer_name)\n    tokens = tokenizer.encode(text)\n    chunks_iterator = batched(tokens, chunk_length)\n    yield from chunks_iterator\n\n\ndef get_ada_embedding(text: str) -> List[float]:\n    \"\"\"Get an embedding from the ada model.\n\n    Args:\n        text (str): The text to embed.\n\n    Returns:\n        List[float]: The embedding.\n    \"\"\"\n    cfg = Config()\n    model = cfg.embedding_model\n    text = text.replace(\"\\n\", \" \")\n\n    if cfg.use_azure:\n        kwargs = {\"engine\": cfg.get_azure_deployment_id_for_model(model)}\n    else:\n        kwargs = {\"model\": model}\n\n    embedding = create_embedding(text, **kwargs)\n    return embedding\n\n\n@retry_openai_api()\ndef create_embedding(\n    text: str,\n    *_,\n    **kwargs,\n) -> openai.Embedding:\n    \"\"\"Create an embedding using the OpenAI API\n\n    Args:\n        text (str): The text to embed.\n        kwargs: Other arguments to pass to the OpenAI API embedding creation call.\n\n    Returns:\n        openai.Embedding: The embedding object.\n    \"\"\"\n    cfg = Config()\n    chunk_embeddings = []\n    chunk_lengths = []\n    for chunk in chunked_tokens(\n        text,\n        tokenizer_name=cfg.embedding_tokenizer,\n        chunk_length=cfg.embedding_token_limit,\n    ):\n        embedding = openai.Embedding.create(\n            input=[chunk],\n            api_key=cfg.openai_api_key,\n            **kwargs,\n        )\n        api_manager = ApiManager()\n        api_manager.update_cost(\n            prompt_tokens=embedding.usage.prompt_tokens,\n            completion_tokens=0,\n            model=cfg.embedding_model,\n        )\n        chunk_embeddings.append(embedding[\"data\"][0][\"embedding\"])\n        chunk_lengths.append(len(chunk))\n\n    # do weighted avg\n    chunk_embeddings = np.average(chunk_embeddings, axis=0, weights=chunk_lengths)\n    chunk_embeddings = chunk_embeddings / np.linalg.norm(\n        chunk_embeddings\n    )  # normalize the length to one\n    chunk_embeddings = chunk_embeddings.tolist()\n    return chunk_embeddings\n"
  },
  {
    "path": "autogpt/llm/modelsinfo.py",
    "content": "COSTS = {\n    \"gpt-3.5-turbo\": {\"prompt\": 0.002, \"completion\": 0.002},\n    \"gpt-3.5-turbo-0301\": {\"prompt\": 0.002, \"completion\": 0.002},\n    \"gpt-4-0314\": {\"prompt\": 0.03, \"completion\": 0.06},\n    \"gpt-4\": {\"prompt\": 0.03, \"completion\": 0.06},\n    \"gpt-4-0314\": {\"prompt\": 0.03, \"completion\": 0.06},\n    \"gpt-4-32k\": {\"prompt\": 0.06, \"completion\": 0.12},\n    \"gpt-4-32k-0314\": {\"prompt\": 0.06, \"completion\": 0.12},\n    \"text-embedding-ada-002\": {\"prompt\": 0.0004, \"completion\": 0.0},\n}\n"
  },
  {
    "path": "autogpt/llm/providers/__init__.py",
    "content": ""
  },
  {
    "path": "autogpt/llm/providers/openai.py",
    "content": "from autogpt.llm.base import ChatModelInfo, EmbeddingModelInfo\n\nOPEN_AI_CHAT_MODELS = {\n    \"gpt-3.5-turbo\": ChatModelInfo(\n        name=\"gpt-3.5-turbo\",\n        prompt_token_cost=0.002,\n        completion_token_cost=0.002,\n        max_tokens=4096,\n    ),\n    \"gpt-4\": ChatModelInfo(\n        name=\"gpt-4\",\n        prompt_token_cost=0.03,\n        completion_token_cost=0.06,\n        max_tokens=8192,\n    ),\n    \"gpt-4-32k\": ChatModelInfo(\n        name=\"gpt-4-32k\",\n        prompt_token_cost=0.06,\n        completion_token_cost=0.12,\n        max_tokens=32768,\n    ),\n}\n\nOPEN_AI_EMBEDDING_MODELS = {\n    \"text-embedding-ada-002\": EmbeddingModelInfo(\n        name=\"text-embedding-ada-002\",\n        prompt_token_cost=0.0004,\n        completion_token_cost=0.0,\n        max_tokens=8191,\n        embedding_dimensions=1536,\n    ),\n}\n\nOPEN_AI_MODELS = {\n    **OPEN_AI_CHAT_MODELS,\n    **OPEN_AI_EMBEDDING_MODELS,\n}\n"
  },
  {
    "path": "autogpt/llm/token_counter.py",
    "content": "\"\"\"Functions for counting the number of tokens in a message or string.\"\"\"\nfrom __future__ import annotations\n\nfrom typing import List\n\nimport tiktoken\n\nfrom autogpt.llm.base import Message\nfrom autogpt.logs import logger\n\n\ndef count_message_tokens(\n    messages: List[Message], model: str = \"gpt-3.5-turbo-0301\"\n) -> int:\n    \"\"\"\n    Returns the number of tokens used by a list of messages.\n\n    Args:\n        messages (list): A list of messages, each of which is a dictionary\n            containing the role and content of the message.\n        model (str): The name of the model to use for tokenization.\n            Defaults to \"gpt-3.5-turbo-0301\".\n\n    Returns:\n        int: The number of tokens used by the list of messages.\n    \"\"\"\n    try:\n        encoding = tiktoken.encoding_for_model(model)\n    except KeyError:\n        logger.warn(\"警告: model没有找到. 使用cl100k_base编码.\")\n        encoding = tiktoken.get_encoding(\"cl100k_base\")\n    if model == \"gpt-3.5-turbo\":\n        # !Note: gpt-3.5-turbo may change over time.\n        # Returning num tokens assuming gpt-3.5-turbo-0301.\")\n        return count_message_tokens(messages, model=\"gpt-3.5-turbo-0301\")\n    elif model == \"gpt-4\":\n        # !Note: gpt-4 may change over time. Returning num tokens assuming gpt-4-0314.\")\n        return count_message_tokens(messages, model=\"gpt-4-0314\")\n    elif model == \"gpt-3.5-turbo-0301\":\n        tokens_per_message = (\n            4  # every message follows <|start|>{role/name}\\n{content}<|end|>\\n\n        )\n        tokens_per_name = -1  # if there's a name, the role is omitted\n    elif model == \"gpt-4-0314\":\n        tokens_per_message = 3\n        tokens_per_name = 1\n    else:\n        raise NotImplementedError(\n            f\"num_tokens_from_messages() is not implemented for model {model}.\\n\"\n            \" See https://github.com/openai/openai-python/blob/main/chatml.md for\"\n            \" information on how messages are converted to tokens.\"\n        )\n    num_tokens = 0\n    for message in messages:\n        num_tokens += tokens_per_message\n        for key, value in message.items():\n            num_tokens += len(encoding.encode(value))\n            if key == \"name\":\n                num_tokens += tokens_per_name\n    num_tokens += 3  # every reply is primed with <|start|>assistant<|message|>\n    return num_tokens\n\n\ndef count_string_tokens(string: str, model_name: str) -> int:\n    \"\"\"\n    Returns the number of tokens in a text string.\n\n    Args:\n        string (str): The text string.\n        model_name (str): The name of the encoding to use. (e.g., \"gpt-3.5-turbo\")\n\n    Returns:\n        int: The number of tokens in the text string.\n    \"\"\"\n    encoding = tiktoken.encoding_for_model(model_name)\n    return len(encoding.encode(string))\n"
  },
  {
    "path": "autogpt/log_cycle/__init__.py",
    "content": ""
  },
  {
    "path": "autogpt/log_cycle/json_handler.py",
    "content": "import json\nimport logging\n\n\nclass JsonFileHandler(logging.FileHandler):\n    def __init__(self, filename, mode=\"a\", encoding=None, delay=False):\n        super().__init__(filename, mode, encoding, delay)\n\n    def emit(self, record):\n        json_data = json.loads(self.format(record))\n        with open(self.baseFilename, \"w\", encoding=\"utf-8\") as f:\n            json.dump(json_data, f, ensure_ascii=False, indent=4)\n\n\nimport logging\n\n\nclass JsonFormatter(logging.Formatter):\n    def format(self, record):\n        return record.msg\n"
  },
  {
    "path": "autogpt/log_cycle/log_cycle.py",
    "content": "import json\nimport os\nfrom typing import Any, Dict, Union\n\nfrom autogpt.logs import logger\n\nDEFAULT_PREFIX = \"agent\"\nFULL_MESSAGE_HISTORY_FILE_NAME = \"full_message_history.json\"\nCURRENT_CONTEXT_FILE_NAME = \"current_context.json\"\nNEXT_ACTION_FILE_NAME = \"next_action.json\"\nPROMPT_SUMMARY_FILE_NAME = \"prompt_summary.json\"\nSUMMARY_FILE_NAME = \"summary.txt\"\nUSER_INPUT_FILE_NAME = \"user_input.txt\"\n\n\nclass LogCycleHandler:\n    \"\"\"\n    A class for logging cycle data.\n    \"\"\"\n\n    def __init__(self):\n        self.log_count_within_cycle = 0\n\n    @staticmethod\n    def create_directory_if_not_exists(directory_path: str) -> None:\n        if not os.path.exists(directory_path):\n            os.makedirs(directory_path, exist_ok=True)\n\n    def create_outer_directory(self, ai_name: str, created_at: str) -> str:\n        log_directory = logger.get_log_directory()\n\n        if os.environ.get(\"OVERWRITE_DEBUG\") == \"1\":\n            outer_folder_name = \"auto_gpt\"\n        else:\n            ai_name_short = ai_name[:15] if ai_name else DEFAULT_PREFIX\n            outer_folder_name = f\"{created_at}_{ai_name_short}\"\n\n        outer_folder_path = os.path.join(log_directory, \"DEBUG\", outer_folder_name)\n        self.create_directory_if_not_exists(outer_folder_path)\n\n        return outer_folder_path\n\n    def create_inner_directory(self, outer_folder_path: str, cycle_count: int) -> str:\n        nested_folder_name = str(cycle_count).zfill(3)\n        nested_folder_path = os.path.join(outer_folder_path, nested_folder_name)\n        self.create_directory_if_not_exists(nested_folder_path)\n\n        return nested_folder_path\n\n    def create_nested_directory(\n        self, ai_name: str, created_at: str, cycle_count: int\n    ) -> str:\n        outer_folder_path = self.create_outer_directory(ai_name, created_at)\n        nested_folder_path = self.create_inner_directory(outer_folder_path, cycle_count)\n\n        return nested_folder_path\n\n    def log_cycle(\n        self,\n        ai_name: str,\n        created_at: str,\n        cycle_count: int,\n        data: Union[Dict[str, Any], Any],\n        file_name: str,\n    ) -> None:\n        \"\"\"\n        Log cycle data to a JSON file.\n\n        Args:\n            data (Any): The data to be logged.\n            file_name (str): The name of the file to save the logged data.\n        \"\"\"\n        nested_folder_path = self.create_nested_directory(\n            ai_name, created_at, cycle_count\n        )\n\n        json_data = json.dumps(data, ensure_ascii=False, indent=4)\n        log_file_path = os.path.join(\n            nested_folder_path, f\"{self.log_count_within_cycle}_{file_name}\"\n        )\n\n        logger.log_json(json_data, log_file_path)\n        self.log_count_within_cycle += 1\n"
  },
  {
    "path": "autogpt/logs.py",
    "content": "\"\"\"Logging module for Auto-GPT.\"\"\"\nimport logging\nimport os\nimport random\nimport re\nimport time\nfrom logging import LogRecord\nfrom typing import Any\n\nfrom colorama import Fore, Style\n\nfrom autogpt.log_cycle.json_handler import JsonFileHandler, JsonFormatter\nfrom autogpt.singleton import Singleton\nfrom autogpt.speech import say_text\n\n\nclass Logger(metaclass=Singleton):\n    \"\"\"\n    Logger that handle titles in different colors.\n    Outputs logs in console, activity.log, and errors.log\n    For console handler: simulates typing\n    \"\"\"\n\n    def __init__(self):\n        # create log directory if it doesn't exist\n        this_files_dir_path = os.path.dirname(__file__)\n        log_dir = os.path.join(this_files_dir_path, \"../logs\")\n        if not os.path.exists(log_dir):\n            os.makedirs(log_dir)\n\n        log_file = \"activity.log\"\n        error_file = \"error.log\"\n\n        console_formatter = AutoGptFormatter(\"%(title_color)s %(message)s\")\n\n        # Create a handler for console which simulate typing\n        self.typing_console_handler = TypingConsoleHandler()\n        self.typing_console_handler.setLevel(logging.INFO)\n        self.typing_console_handler.setFormatter(console_formatter)\n\n        # Create a handler for console without typing simulation\n        self.console_handler = ConsoleHandler()\n        self.console_handler.setLevel(logging.DEBUG)\n        self.console_handler.setFormatter(console_formatter)\n\n        # Info handler in activity.log\n        self.file_handler = logging.FileHandler(\n            os.path.join(log_dir, log_file), \"a\", \"utf-8\"\n        )\n        self.file_handler.setLevel(logging.DEBUG)\n        info_formatter = AutoGptFormatter(\n            \"%(asctime)s %(levelname)s %(title)s %(message_no_color)s\"\n        )\n        self.file_handler.setFormatter(info_formatter)\n\n        # Error handler error.log\n        error_handler = logging.FileHandler(\n            os.path.join(log_dir, error_file), \"a\", \"utf-8\"\n        )\n        error_handler.setLevel(logging.ERROR)\n        error_formatter = AutoGptFormatter(\n            \"%(asctime)s %(levelname)s %(module)s:%(funcName)s:%(lineno)d %(title)s\"\n            \" %(message_no_color)s\"\n        )\n        error_handler.setFormatter(error_formatter)\n\n        self.typing_logger = logging.getLogger(\"TYPER\")\n        self.typing_logger.addHandler(self.typing_console_handler)\n        self.typing_logger.addHandler(self.file_handler)\n        self.typing_logger.addHandler(error_handler)\n        self.typing_logger.setLevel(logging.DEBUG)\n\n        self.logger = logging.getLogger(\"LOGGER\")\n        self.logger.addHandler(self.console_handler)\n        self.logger.addHandler(self.file_handler)\n        self.logger.addHandler(error_handler)\n        self.logger.setLevel(logging.DEBUG)\n\n        self.json_logger = logging.getLogger(\"JSON_LOGGER\")\n        self.json_logger.addHandler(self.file_handler)\n        self.json_logger.addHandler(error_handler)\n        self.json_logger.setLevel(logging.DEBUG)\n\n        self.speak_mode = False\n        self.chat_plugins = []\n\n    def typewriter_log(\n        self, title=\"\", title_color=\"\", content=\"\", speak_text=False, level=logging.INFO\n    ):\n        if speak_text and self.speak_mode:\n            say_text(f\"{title}. {content}\")\n\n        for plugin in self.chat_plugins:\n            plugin.report(f\"{title}. {content}\")\n\n        if content:\n            if isinstance(content, list):\n                content = \" \".join(content)\n        else:\n            content = \"\"\n\n        self.typing_logger.log(\n            level, content, extra={\"title\": title, \"color\": title_color}\n        )\n\n    def debug(\n        self,\n        message,\n        title=\"\",\n        title_color=\"\",\n    ):\n        self._log(title, title_color, message, logging.DEBUG)\n\n    def info(\n        self,\n        message,\n        title=\"\",\n        title_color=\"\",\n    ):\n        self._log(title, title_color, message, logging.INFO)\n\n    def warn(\n        self,\n        message,\n        title=\"\",\n        title_color=\"\",\n    ):\n        self._log(title, title_color, message, logging.WARN)\n\n    def error(self, title, message=\"\"):\n        self._log(title, Fore.RED, message, logging.ERROR)\n\n    def _log(\n        self,\n        title: str = \"\",\n        title_color: str = \"\",\n        message: str = \"\",\n        level=logging.INFO,\n    ):\n        if message:\n            if isinstance(message, list):\n                message = \" \".join(message)\n        self.logger.log(\n            level, message, extra={\"title\": str(title), \"color\": str(title_color)}\n        )\n\n    def set_level(self, level):\n        self.logger.setLevel(level)\n        self.typing_logger.setLevel(level)\n\n    def double_check(self, additionalText=None):\n        if not additionalText:\n            additionalText = (\n                \"请确认你已经正确配置好所有内容\"\n                \" 请阅读 https://github.com/Torantulino/Auto-GPT#readme \"\n                \"确认. 你也可以在Github上开启Issue或者去Discord讨论\"\n                \"!\"\n            )\n\n        self.typewriter_log(\"请再次检查配置\", Fore.YELLOW, additionalText)\n\n    def log_json(self, data: Any, file_name: str) -> None:\n        # Define log directory\n        this_files_dir_path = os.path.dirname(__file__)\n        log_dir = os.path.join(this_files_dir_path, \"../logs\")\n\n        # Create a handler for JSON files\n        json_file_path = os.path.join(log_dir, file_name)\n        json_data_handler = JsonFileHandler(json_file_path)\n        json_data_handler.setFormatter(JsonFormatter())\n\n        # Log the JSON data using the custom file handler\n        self.json_logger.addHandler(json_data_handler)\n        self.json_logger.debug(data)\n        self.json_logger.removeHandler(json_data_handler)\n\n    def get_log_directory(self):\n        this_files_dir_path = os.path.dirname(__file__)\n        log_dir = os.path.join(this_files_dir_path, \"../logs\")\n        return os.path.abspath(log_dir)\n\n\n\"\"\"\nOutput stream to console using simulated typing\n\"\"\"\n\n\nclass TypingConsoleHandler(logging.StreamHandler):\n    def emit(self, record):\n        min_typing_speed = 0.05\n        max_typing_speed = 0.01\n\n        msg = self.format(record)\n        try:\n            words = msg.split()\n            for i, word in enumerate(words):\n                print(word, end=\"\", flush=True)\n                if i < len(words) - 1:\n                    print(\" \", end=\"\", flush=True)\n                typing_speed = random.uniform(min_typing_speed, max_typing_speed)\n                time.sleep(typing_speed)\n                # type faster after each word\n                min_typing_speed = min_typing_speed * 0.95\n                max_typing_speed = max_typing_speed * 0.95\n            print()\n        except Exception:\n            self.handleError(record)\n\n\nclass ConsoleHandler(logging.StreamHandler):\n    def emit(self, record) -> None:\n        msg = self.format(record)\n        try:\n            print(msg)\n        except Exception:\n            self.handleError(record)\n\n\nclass AutoGptFormatter(logging.Formatter):\n    \"\"\"\n    Allows to handle custom placeholders 'title_color' and 'message_no_color'.\n    To use this formatter, make sure to pass 'color', 'title' as log extras.\n    \"\"\"\n\n    def format(self, record: LogRecord) -> str:\n        if hasattr(record, \"color\"):\n            record.title_color = (\n                getattr(record, \"color\")\n                + getattr(record, \"title\", \"\")\n                + \" \"\n                + Style.RESET_ALL\n            )\n        else:\n            record.title_color = getattr(record, \"title\", \"\")\n\n        # Add this line to set 'title' to an empty string if it doesn't exist\n        record.title = getattr(record, \"title\", \"\")\n\n        if hasattr(record, \"msg\"):\n            record.message_no_color = remove_color_codes(getattr(record, \"msg\"))\n        else:\n            record.message_no_color = \"\"\n        return super().format(record)\n\n\ndef remove_color_codes(s: str) -> str:\n    ansi_escape = re.compile(r\"\\x1B(?:[@-Z\\\\-_]|\\[[0-?]*[ -/]*[@-~])\")\n    return ansi_escape.sub(\"\", s)\n\n\nlogger = Logger()\n\n\ndef print_assistant_thoughts(\n    ai_name: object,\n    assistant_reply_json_valid: object,\n    speak_mode: bool = False,\n) -> None:\n    assistant_thoughts_reasoning = None\n    assistant_thoughts_plan = None\n    assistant_thoughts_speak = None\n    assistant_thoughts_criticism = None\n\n    assistant_thoughts = assistant_reply_json_valid.get(\"thoughts\", {})\n    assistant_thoughts_text = assistant_thoughts.get(\"text\")\n    if assistant_thoughts:\n        assistant_thoughts_reasoning = assistant_thoughts.get(\"reasoning\")\n        assistant_thoughts_plan = assistant_thoughts.get(\"plan\")\n        assistant_thoughts_criticism = assistant_thoughts.get(\"criticism\")\n        assistant_thoughts_speak = assistant_thoughts.get(\"speak\")\n    logger.typewriter_log(\n        f\"{ai_name.upper()}思考:\", Fore.YELLOW, f\"{assistant_thoughts_text}\"\n    )\n    logger.typewriter_log(\"推理:\", Fore.YELLOW, f\"{assistant_thoughts_reasoning}\")\n    if assistant_thoughts_plan:\n        logger.typewriter_log(\"计划:\", Fore.YELLOW, \"\")\n        # If it's a list, join it into a string\n        if isinstance(assistant_thoughts_plan, list):\n            assistant_thoughts_plan = \"\\n\".join(assistant_thoughts_plan)\n        elif isinstance(assistant_thoughts_plan, dict):\n            assistant_thoughts_plan = str(assistant_thoughts_plan)\n\n        # Split the input_string using the newline character and dashes\n        lines = assistant_thoughts_plan.split(\"\\n\")\n        for line in lines:\n            line = line.lstrip(\"- \")\n            logger.typewriter_log(\"- \", Fore.GREEN, line.strip())\n    logger.typewriter_log(\"反思:\", Fore.YELLOW, f\"{assistant_thoughts_criticism}\")\n    # Speak the assistant's thoughts\n    if speak_mode and assistant_thoughts_speak:\n        say_text(assistant_thoughts_speak)\n"
  },
  {
    "path": "autogpt/main.py",
    "content": "\"\"\"The application entry point.  Can be invoked by a CLI or any other front end application.\"\"\"\nimport logging\nimport sys\nfrom pathlib import Path\n\nfrom colorama import Fore, Style\n\nfrom autogpt.agent.agent import Agent\nfrom autogpt.commands.command import CommandRegistry\nfrom autogpt.config import Config, check_openai_api_key\nfrom autogpt.configurator import create_config\nfrom autogpt.logs import logger\nfrom autogpt.memory import get_memory\nfrom autogpt.plugins import scan_plugins\nfrom autogpt.prompts.prompt import DEFAULT_TRIGGERING_PROMPT, construct_main_ai_config\nfrom autogpt.utils import (\n    get_current_git_branch,\n    get_latest_bulletin,\n    markdown_to_ansi_style,\n)\nfrom autogpt.workspace import Workspace\nfrom scripts.install_plugin_deps import install_plugin_dependencies\n\n\ndef run_auto_gpt(\n    continuous: bool,\n    continuous_limit: int,\n    ai_settings: str,\n    skip_reprompt: bool,\n    speak: bool,\n    debug: bool,\n    gpt3only: bool,\n    gpt4only: bool,\n    memory_type: str,\n    browser_name: str,\n    allow_downloads: bool,\n    skip_news: bool,\n    workspace_directory: str,\n    install_plugin_deps: bool,\n):\n    # Configure logging before we do anything else.\n    logger.set_level(logging.DEBUG if debug else logging.INFO)\n    logger.speak_mode = speak\n\n    cfg = Config()\n    # TODO: fill in llm values here\n    check_openai_api_key()\n    create_config(\n        continuous,\n        continuous_limit,\n        ai_settings,\n        skip_reprompt,\n        speak,\n        debug,\n        gpt3only,\n        gpt4only,\n        memory_type,\n        browser_name,\n        allow_downloads,\n        skip_news,\n    )\n\n    if not cfg.skip_news:\n        motd, is_new_motd = get_latest_bulletin()\n        if motd:\n            motd = markdown_to_ansi_style(motd)\n            for motd_line in motd.split(\"\\n\"):\n                logger.info(motd_line, \"新闻:\", Fore.GREEN)\n            if is_new_motd and not cfg.chat_messages_enabled:\n                input(\n                    Fore.MAGENTA\n                    + Style.BRIGHT\n                    + \"NEWS: 最新信息已经更新，按回车继续...\"\n                    + Style.RESET_ALL\n                )\n\n        git_branch = get_current_git_branch()\n        if git_branch and git_branch != \"stable\":\n            logger.typewriter_log(\n                \"警告: \",\n                Fore.RED,\n                f\"你正在运行的是 `{git_branch}` 分支 \"\n                \"- 该分支不被支持.\",\n            )\n        if sys.version_info < (3, 10):\n            logger.typewriter_log(\n                \"警告: \",\n                Fore.RED,\n                \"你正在运行较低版本的Python. \"\n                \"有些朋友在这个过程中会出现一系列问题\"\n                \"建议更新你的Python至3.10或更高.\",\n            )\n\n    if install_plugin_deps:\n        install_plugin_dependencies()\n\n    # TODO: have this directory live outside the repository (e.g. in a user's\n    #   home directory) and have it come in as a command line argument or part of\n    #   the env file.\n    if workspace_directory is None:\n        workspace_directory = Path(__file__).parent / \"auto_gpt_workspace\"\n    else:\n        workspace_directory = Path(workspace_directory)\n    # TODO: pass in the ai_settings file and the env file and have them cloned into\n    #   the workspace directory so we can bind them to the agent.\n    workspace_directory = Workspace.make_workspace(workspace_directory)\n    cfg.workspace_path = str(workspace_directory)\n\n    # HACK: doing this here to collect some globals that depend on the workspace.\n    file_logger_path = workspace_directory / \"file_logger.txt\"\n    if not file_logger_path.exists():\n        with file_logger_path.open(mode=\"w\", encoding=\"utf-8\") as f:\n            f.write(\"File Operation Logger \")\n\n    cfg.file_logger_path = str(file_logger_path)\n\n    cfg.set_plugins(scan_plugins(cfg, cfg.debug_mode))\n    # Create a CommandRegistry instance and scan default folder\n    command_registry = CommandRegistry()\n    command_registry.import_commands(\"autogpt.commands.analyze_code\")\n    command_registry.import_commands(\"autogpt.commands.audio_text\")\n    command_registry.import_commands(\"autogpt.commands.execute_code\")\n    command_registry.import_commands(\"autogpt.commands.file_operations\")\n    command_registry.import_commands(\"autogpt.commands.git_operations\")\n    command_registry.import_commands(\"autogpt.commands.google_search\")\n    command_registry.import_commands(\"autogpt.commands.image_gen\")\n    command_registry.import_commands(\"autogpt.commands.improve_code\")\n    command_registry.import_commands(\"autogpt.commands.twitter\")\n    command_registry.import_commands(\"autogpt.commands.web_selenium\")\n    command_registry.import_commands(\"autogpt.commands.write_tests\")\n    command_registry.import_commands(\"autogpt.app\")\n\n    ai_name = \"\"\n    ai_config = construct_main_ai_config()\n    ai_config.command_registry = command_registry\n    # print(prompt)\n    # Initialize variables\n    full_message_history = []\n    next_action_count = 0\n\n    # add chat plugins capable of report to logger\n    if cfg.chat_messages_enabled:\n        for plugin in cfg.plugins:\n            if hasattr(plugin, \"can_handle_report\") and plugin.can_handle_report():\n                logger.info(f\"Loaded plugin into logger: {plugin.__class__.__name__}\")\n                logger.chat_plugins.append(plugin)\n\n    # Initialize memory and make sure it is empty.\n    # this is particularly important for indexing and referencing pinecone memory\n    memory = get_memory(cfg, init=True)\n    logger.typewriter_log(\n        \"Using memory of type:\", Fore.GREEN, f\"{memory.__class__.__name__}\"\n    )\n    logger.typewriter_log(\"Using Browser:\", Fore.GREEN, cfg.selenium_web_browser)\n    system_prompt = ai_config.construct_full_prompt()\n    if cfg.debug_mode:\n        logger.typewriter_log(\"Prompt:\", Fore.GREEN, system_prompt)\n\n    agent = Agent(\n        ai_name=ai_name,\n        memory=memory,\n        full_message_history=full_message_history,\n        next_action_count=next_action_count,\n        command_registry=command_registry,\n        config=ai_config,\n        system_prompt=system_prompt,\n        triggering_prompt=DEFAULT_TRIGGERING_PROMPT,\n        workspace_directory=workspace_directory,\n    )\n    agent.start_interaction_loop()\n"
  },
  {
    "path": "autogpt/memory/__init__.py",
    "content": "from autogpt.logs import logger\nfrom autogpt.memory.local import LocalCache\nfrom autogpt.memory.no_memory import NoMemory\n\n# List of supported memory backends\n# Add a backend to this list if the import attempt is successful\nsupported_memory = [\"local\", \"no_memory\"]\n\ntry:\n    from autogpt.memory.redismem import RedisMemory\n\n    supported_memory.append(\"redis\")\nexcept ImportError:\n    RedisMemory = None\n\ntry:\n    from autogpt.memory.pinecone import PineconeMemory\n\n    supported_memory.append(\"pinecone\")\nexcept ImportError:\n    PineconeMemory = None\n\ntry:\n    from autogpt.memory.weaviate import WeaviateMemory\n\n    supported_memory.append(\"weaviate\")\nexcept ImportError:\n    WeaviateMemory = None\n\ntry:\n    from autogpt.memory.milvus import MilvusMemory\n\n    supported_memory.append(\"milvus\")\nexcept ImportError:\n    MilvusMemory = None\n\n\ndef get_memory(cfg, init=False):\n    memory = None\n    if cfg.memory_backend == \"pinecone\":\n        if not PineconeMemory:\n            logger.warn(\n                \"Error: Pinecone is not installed. Please install pinecone\"\n                \" to use Pinecone as a memory backend.\"\n            )\n        else:\n            memory = PineconeMemory(cfg)\n            if init:\n                memory.clear()\n    elif cfg.memory_backend == \"redis\":\n        if not RedisMemory:\n            logger.warn(\n                \"Error: Redis is not installed. Please install redis-py to\"\n                \" use Redis as a memory backend.\"\n            )\n        else:\n            memory = RedisMemory(cfg)\n    elif cfg.memory_backend == \"weaviate\":\n        if not WeaviateMemory:\n            logger.warn(\n                \"Error: Weaviate is not installed. Please install weaviate-client to\"\n                \" use Weaviate as a memory backend.\"\n            )\n        else:\n            memory = WeaviateMemory(cfg)\n    elif cfg.memory_backend == \"milvus\":\n        if not MilvusMemory:\n            logger.warn(\n                \"Error: pymilvus sdk is not installed.\"\n                \"Please install pymilvus to use Milvus or Zilliz Cloud as memory backend.\"\n            )\n        else:\n            memory = MilvusMemory(cfg)\n    elif cfg.memory_backend == \"no_memory\":\n        memory = NoMemory(cfg)\n\n    if memory is None:\n        memory = LocalCache(cfg)\n        if init:\n            memory.clear()\n    return memory\n\n\ndef get_supported_memory_backends():\n    return supported_memory\n\n\n__all__ = [\n    \"get_memory\",\n    \"LocalCache\",\n    \"RedisMemory\",\n    \"PineconeMemory\",\n    \"NoMemory\",\n    \"MilvusMemory\",\n    \"WeaviateMemory\",\n]\n"
  },
  {
    "path": "autogpt/memory/base.py",
    "content": "\"\"\"Base class for memory providers.\"\"\"\nimport abc\n\nfrom autogpt.singleton import AbstractSingleton\n\n\nclass MemoryProviderSingleton(AbstractSingleton):\n    @abc.abstractmethod\n    def add(self, data):\n        \"\"\"Adds to memory\"\"\"\n        pass\n\n    @abc.abstractmethod\n    def get(self, data):\n        \"\"\"Gets from memory\"\"\"\n        pass\n\n    @abc.abstractmethod\n    def clear(self):\n        \"\"\"Clears memory\"\"\"\n        pass\n\n    @abc.abstractmethod\n    def get_relevant(self, data, num_relevant=5):\n        \"\"\"Gets relevant memory for\"\"\"\n        pass\n\n    @abc.abstractmethod\n    def get_stats(self):\n        \"\"\"Get stats from memory\"\"\"\n        pass\n"
  },
  {
    "path": "autogpt/memory/local.py",
    "content": "from __future__ import annotations\n\nimport dataclasses\nfrom pathlib import Path\nfrom typing import Any, List\n\nimport numpy as np\nimport orjson\n\nfrom autogpt.llm import get_ada_embedding\nfrom autogpt.memory.base import MemoryProviderSingleton\n\nEMBED_DIM = 1536\nSAVE_OPTIONS = orjson.OPT_SERIALIZE_NUMPY | orjson.OPT_SERIALIZE_DATACLASS\n\n\ndef create_default_embeddings():\n    return np.zeros((0, EMBED_DIM)).astype(np.float32)\n\n\n@dataclasses.dataclass\nclass CacheContent:\n    texts: List[str] = dataclasses.field(default_factory=list)\n    embeddings: np.ndarray = dataclasses.field(\n        default_factory=create_default_embeddings\n    )\n\n\nclass LocalCache(MemoryProviderSingleton):\n    \"\"\"A class that stores the memory in a local file\"\"\"\n\n    def __init__(self, cfg) -> None:\n        \"\"\"Initialize a class instance\n\n        Args:\n            cfg: Config object\n\n        Returns:\n            None\n        \"\"\"\n        workspace_path = Path(cfg.workspace_path)\n        self.filename = workspace_path / f\"{cfg.memory_index}.json\"\n\n        self.filename.touch(exist_ok=True)\n\n        file_content = b\"{}\"\n        with self.filename.open(\"w+b\") as f:\n            f.write(file_content)\n\n        self.data = CacheContent()\n\n    def add(self, text: str):\n        \"\"\"\n        Add text to our list of texts, add embedding as row to our\n            embeddings-matrix\n\n        Args:\n            text: str\n\n        Returns: None\n        \"\"\"\n        if \"Command Error:\" in text:\n            return \"\"\n        self.data.texts.append(text)\n\n        embedding = get_ada_embedding(text)\n\n        vector = np.array(embedding).astype(np.float32)\n        vector = vector[np.newaxis, :]\n        self.data.embeddings = np.concatenate(\n            [\n                self.data.embeddings,\n                vector,\n            ],\n            axis=0,\n        )\n\n        with open(self.filename, \"wb\") as f:\n            out = orjson.dumps(self.data, option=SAVE_OPTIONS)\n            f.write(out)\n        return text\n\n    def clear(self) -> str:\n        \"\"\"\n        Clears the data in memory.\n\n        Returns: A message indicating that the memory has been cleared.\n        \"\"\"\n        self.data = CacheContent()\n        return \"Obliviated\"\n\n    def get(self, data: str) -> list[Any] | None:\n        \"\"\"\n        Gets the data from the memory that is most relevant to the given data.\n\n        Args:\n            data: The data to compare to.\n\n        Returns: The most relevant data.\n        \"\"\"\n        return self.get_relevant(data, 1)\n\n    def get_relevant(self, text: str, k: int) -> list[Any]:\n        \"\"\" \"\n        matrix-vector mult to find score-for-each-row-of-matrix\n         get indices for top-k winning scores\n         return texts for those indices\n        Args:\n            text: str\n            k: int\n\n        Returns: List[str]\n        \"\"\"\n        embedding = get_ada_embedding(text)\n\n        scores = np.dot(self.data.embeddings, embedding)\n\n        top_k_indices = np.argsort(scores)[-k:][::-1]\n\n        return [self.data.texts[i] for i in top_k_indices]\n\n    def get_stats(self) -> tuple[int, tuple[int, ...]]:\n        \"\"\"\n        Returns: The stats of the local cache.\n        \"\"\"\n        return len(self.data.texts), self.data.embeddings.shape\n"
  },
  {
    "path": "autogpt/memory/milvus.py",
    "content": "\"\"\" Milvus memory storage provider.\"\"\"\nimport re\n\nfrom pymilvus import Collection, CollectionSchema, DataType, FieldSchema, connections\n\nfrom autogpt.config import Config\nfrom autogpt.llm import get_ada_embedding\nfrom autogpt.memory.base import MemoryProviderSingleton\n\n\nclass MilvusMemory(MemoryProviderSingleton):\n    \"\"\"Milvus memory storage provider.\"\"\"\n\n    def __init__(self, cfg: Config) -> None:\n        \"\"\"Construct a milvus memory storage connection.\n\n        Args:\n            cfg (Config): Auto-GPT global config.\n        \"\"\"\n        self.configure(cfg)\n\n        connect_kwargs = {}\n        if self.username:\n            connect_kwargs[\"user\"] = self.username\n            connect_kwargs[\"password\"] = self.password\n\n        connections.connect(\n            **connect_kwargs,\n            uri=self.uri or \"\",\n            address=self.address or \"\",\n            secure=self.secure,\n        )\n\n        self.init_collection()\n\n    def configure(self, cfg: Config) -> None:\n        # init with configuration.\n        self.uri = None\n        self.address = cfg.milvus_addr\n        self.secure = cfg.milvus_secure\n        self.username = cfg.milvus_username\n        self.password = cfg.milvus_password\n        self.collection_name = cfg.milvus_collection\n        # use HNSW by default.\n        self.index_params = {\n            \"metric_type\": \"IP\",\n            \"index_type\": \"HNSW\",\n            \"params\": {\"M\": 8, \"efConstruction\": 64},\n        }\n\n        if (self.username is None) != (self.password is None):\n            raise ValueError(\n                \"Both username and password must be set to use authentication for Milvus\"\n            )\n\n        # configured address may be a full URL.\n        if re.match(r\"^(https?|tcp)://\", self.address) is not None:\n            self.uri = self.address\n            self.address = None\n\n            if self.uri.startswith(\"https\"):\n                self.secure = True\n\n            # Zilliz Cloud requires AutoIndex.\n            if re.match(r\"^https://(.*)\\.zillizcloud\\.(com|cn)\", self.uri) is not None:\n                self.index_params = {\n                    \"metric_type\": \"IP\",\n                    \"index_type\": \"AUTOINDEX\",\n                    \"params\": {},\n                }\n\n    def init_collection(self) -> None:\n        \"\"\"Initialize collection in vector database.\"\"\"\n        fields = [\n            FieldSchema(name=\"pk\", dtype=DataType.INT64, is_primary=True, auto_id=True),\n            FieldSchema(name=\"embeddings\", dtype=DataType.FLOAT_VECTOR, dim=1536),\n            FieldSchema(name=\"raw_text\", dtype=DataType.VARCHAR, max_length=65535),\n        ]\n\n        # create collection if not exist and load it.\n        self.schema = CollectionSchema(fields, \"auto-gpt memory storage\")\n        self.collection = Collection(self.collection_name, self.schema)\n        # create index if not exist.\n        if not self.collection.has_index():\n            self.collection.release()\n            self.collection.create_index(\n                \"embeddings\",\n                self.index_params,\n                index_name=\"embeddings\",\n            )\n        self.collection.load()\n\n    def add(self, data) -> str:\n        \"\"\"Add an embedding of data into memory.\n\n        Args:\n            data (str): The raw text to construct embedding index.\n\n        Returns:\n            str: log.\n        \"\"\"\n        embedding = get_ada_embedding(data)\n        result = self.collection.insert([[embedding], [data]])\n        _text = (\n            \"Inserting data into memory at primary key: \"\n            f\"{result.primary_keys[0]}:\\n data: {data}\"\n        )\n        return _text\n\n    def get(self, data):\n        \"\"\"Return the most relevant data in memory.\n        Args:\n            data: The data to compare to.\n        \"\"\"\n        return self.get_relevant(data, 1)\n\n    def clear(self) -> str:\n        \"\"\"Drop the index in memory.\n\n        Returns:\n            str: log.\n        \"\"\"\n        self.collection.drop()\n        self.collection = Collection(self.collection_name, self.schema)\n        self.collection.create_index(\n            \"embeddings\",\n            self.index_params,\n            index_name=\"embeddings\",\n        )\n        self.collection.load()\n        return \"Obliviated\"\n\n    def get_relevant(self, data: str, num_relevant: int = 5):\n        \"\"\"Return the top-k relevant data in memory.\n        Args:\n            data: The data to compare to.\n            num_relevant (int, optional): The max number of relevant data.\n                Defaults to 5.\n\n        Returns:\n            list: The top-k relevant data.\n        \"\"\"\n        # search the embedding and return the most relevant text.\n        embedding = get_ada_embedding(data)\n        search_params = {\n            \"metrics_type\": \"IP\",\n            \"params\": {\"nprobe\": 8},\n        }\n        result = self.collection.search(\n            [embedding],\n            \"embeddings\",\n            search_params,\n            num_relevant,\n            output_fields=[\"raw_text\"],\n        )\n        return [item.entity.value_of_field(\"raw_text\") for item in result[0]]\n\n    def get_stats(self) -> str:\n        \"\"\"\n        Returns: The stats of the milvus cache.\n        \"\"\"\n        return f\"Entities num: {self.collection.num_entities}\"\n"
  },
  {
    "path": "autogpt/memory/no_memory.py",
    "content": "\"\"\"A class that does not store any data. This is the default memory provider.\"\"\"\nfrom __future__ import annotations\n\nfrom typing import Any\n\nfrom autogpt.memory.base import MemoryProviderSingleton\n\n\nclass NoMemory(MemoryProviderSingleton):\n    \"\"\"\n    A class that does not store any data. This is the default memory provider.\n    \"\"\"\n\n    def __init__(self, cfg):\n        \"\"\"\n        Initializes the NoMemory provider.\n\n        Args:\n            cfg: The config object.\n\n        Returns: None\n        \"\"\"\n        pass\n\n    def add(self, data: str) -> str:\n        \"\"\"\n        Adds a data point to the memory. No action is taken in NoMemory.\n\n        Args:\n            data: The data to add.\n\n        Returns: An empty string.\n        \"\"\"\n        return \"\"\n\n    def get(self, data: str) -> list[Any] | None:\n        \"\"\"\n        Gets the data from the memory that is most relevant to the given data.\n        NoMemory always returns None.\n\n        Args:\n            data: The data to compare to.\n\n        Returns: None\n        \"\"\"\n        return None\n\n    def clear(self) -> str:\n        \"\"\"\n        Clears the memory. No action is taken in NoMemory.\n\n        Returns: An empty string.\n        \"\"\"\n        return \"\"\n\n    def get_relevant(self, data: str, num_relevant: int = 5) -> list[Any] | None:\n        \"\"\"\n        Returns all the data in the memory that is relevant to the given data.\n        NoMemory always returns None.\n\n        Args:\n            data: The data to compare to.\n            num_relevant: The number of relevant data to return.\n\n        Returns: None\n        \"\"\"\n        return None\n\n    def get_stats(self):\n        \"\"\"\n        Returns: An empty dictionary as there are no stats in NoMemory.\n        \"\"\"\n        return {}\n"
  },
  {
    "path": "autogpt/memory/pinecone.py",
    "content": "import pinecone\nfrom colorama import Fore, Style\n\nfrom autogpt.llm import get_ada_embedding\nfrom autogpt.logs import logger\nfrom autogpt.memory.base import MemoryProviderSingleton\n\n\nclass PineconeMemory(MemoryProviderSingleton):\n    def __init__(self, cfg):\n        pinecone_api_key = cfg.pinecone_api_key\n        pinecone_region = cfg.pinecone_region\n        pinecone.init(api_key=pinecone_api_key, environment=pinecone_region)\n        dimension = 1536\n        metric = \"cosine\"\n        pod_type = \"p1\"\n        table_name = \"auto-gpt\"\n        # this assumes we don't start with memory.\n        # for now this works.\n        # we'll need a more complicated and robust system if we want to start with\n        #  memory.\n        self.vec_num = 0\n\n        try:\n            pinecone.whoami()\n        except Exception as e:\n            logger.typewriter_log(\n                \"FAILED TO CONNECT TO PINECONE\",\n                Fore.RED,\n                Style.BRIGHT + str(e) + Style.RESET_ALL,\n            )\n            logger.double_check(\n                \"Please ensure you have setup and configured Pinecone properly for use.\"\n                + f\"You can check out {Fore.CYAN + Style.BRIGHT}\"\n                \"https://github.com/Torantulino/Auto-GPT#-pinecone-api-key-setup\"\n                f\"{Style.RESET_ALL} to ensure you've set up everything correctly.\"\n            )\n            exit(1)\n\n        if table_name not in pinecone.list_indexes():\n            logger.typewriter_log(\n                \"Connecting Pinecone. This may take some time...\", Fore.MAGENTA, \"\"\n            )\n            pinecone.create_index(\n                table_name, dimension=dimension, metric=metric, pod_type=pod_type\n            )\n        self.index = pinecone.Index(table_name)\n\n    def add(self, data):\n        vector = get_ada_embedding(data)\n        # no metadata here. We may wish to change that long term.\n        self.index.upsert([(str(self.vec_num), vector, {\"raw_text\": data})])\n        _text = f\"Inserting data into memory at index: {self.vec_num}:\\n data: {data}\"\n        self.vec_num += 1\n        return _text\n\n    def get(self, data):\n        return self.get_relevant(data, 1)\n\n    def clear(self):\n        self.index.delete(deleteAll=True)\n        return \"Obliviated\"\n\n    def get_relevant(self, data, num_relevant=5):\n        \"\"\"\n        Returns all the data in the memory that is relevant to the given data.\n        :param data: The data to compare to.\n        :param num_relevant: The number of relevant data to return. Defaults to 5\n        \"\"\"\n        query_embedding = get_ada_embedding(data)\n        results = self.index.query(\n            query_embedding, top_k=num_relevant, include_metadata=True\n        )\n        sorted_results = sorted(results.matches, key=lambda x: x.score)\n        return [str(item[\"metadata\"][\"raw_text\"]) for item in sorted_results]\n\n    def get_stats(self):\n        return self.index.describe_index_stats()\n"
  },
  {
    "path": "autogpt/memory/redismem.py",
    "content": "\"\"\"Redis memory provider.\"\"\"\nfrom __future__ import annotations\n\nfrom typing import Any\n\nimport numpy as np\nimport redis\nfrom colorama import Fore, Style\nfrom redis.commands.search.field import TextField, VectorField\nfrom redis.commands.search.indexDefinition import IndexDefinition, IndexType\nfrom redis.commands.search.query import Query\n\nfrom autogpt.llm import get_ada_embedding\nfrom autogpt.logs import logger\nfrom autogpt.memory.base import MemoryProviderSingleton\n\nSCHEMA = [\n    TextField(\"data\"),\n    VectorField(\n        \"embedding\",\n        \"HNSW\",\n        {\"TYPE\": \"FLOAT32\", \"DIM\": 1536, \"DISTANCE_METRIC\": \"COSINE\"},\n    ),\n]\n\n\nclass RedisMemory(MemoryProviderSingleton):\n    def __init__(self, cfg):\n        \"\"\"\n        Initializes the Redis memory provider.\n\n        Args:\n            cfg: The config object.\n\n        Returns: None\n        \"\"\"\n        redis_host = cfg.redis_host\n        redis_port = cfg.redis_port\n        redis_password = cfg.redis_password\n        self.dimension = 1536\n        self.redis = redis.Redis(\n            host=redis_host,\n            port=redis_port,\n            password=redis_password,\n            db=0,  # Cannot be changed\n        )\n        self.cfg = cfg\n\n        # Check redis connection\n        try:\n            self.redis.ping()\n        except redis.ConnectionError as e:\n            logger.typewriter_log(\n                \"FAILED TO CONNECT TO REDIS\",\n                Fore.RED,\n                Style.BRIGHT + str(e) + Style.RESET_ALL,\n            )\n            logger.double_check(\n                \"Please ensure you have setup and configured Redis properly for use. \"\n                + f\"You can check out {Fore.CYAN + Style.BRIGHT}\"\n                f\"https://github.com/Torantulino/Auto-GPT#redis-setup{Style.RESET_ALL}\"\n                \" to ensure you've set up everything correctly.\"\n            )\n            exit(1)\n\n        if cfg.wipe_redis_on_start:\n            self.redis.flushall()\n        try:\n            self.redis.ft(f\"{cfg.memory_index}\").create_index(\n                fields=SCHEMA,\n                definition=IndexDefinition(\n                    prefix=[f\"{cfg.memory_index}:\"], index_type=IndexType.HASH\n                ),\n            )\n        except Exception as e:\n            logger.warn(\"Error creating Redis search index: \", e)\n        existing_vec_num = self.redis.get(f\"{cfg.memory_index}-vec_num\")\n        self.vec_num = int(existing_vec_num.decode(\"utf-8\")) if existing_vec_num else 0\n\n    def add(self, data: str) -> str:\n        \"\"\"\n        Adds a data point to the memory.\n\n        Args:\n            data: The data to add.\n\n        Returns: Message indicating that the data has been added.\n        \"\"\"\n        if \"Command Error:\" in data:\n            return \"\"\n        vector = get_ada_embedding(data)\n        vector = np.array(vector).astype(np.float32).tobytes()\n        data_dict = {b\"data\": data, \"embedding\": vector}\n        pipe = self.redis.pipeline()\n        pipe.hset(f\"{self.cfg.memory_index}:{self.vec_num}\", mapping=data_dict)\n        _text = (\n            f\"Inserting data into memory at index: {self.vec_num}:\\n\" f\"data: {data}\"\n        )\n        self.vec_num += 1\n        pipe.set(f\"{self.cfg.memory_index}-vec_num\", self.vec_num)\n        pipe.execute()\n        return _text\n\n    def get(self, data: str) -> list[Any] | None:\n        \"\"\"\n        Gets the data from the memory that is most relevant to the given data.\n\n        Args:\n            data: The data to compare to.\n\n        Returns: The most relevant data.\n        \"\"\"\n        return self.get_relevant(data, 1)\n\n    def clear(self) -> str:\n        \"\"\"\n        Clears the redis server.\n\n        Returns: A message indicating that the memory has been cleared.\n        \"\"\"\n        self.redis.flushall()\n        return \"Obliviated\"\n\n    def get_relevant(self, data: str, num_relevant: int = 5) -> list[Any] | None:\n        \"\"\"\n        Returns all the data in the memory that is relevant to the given data.\n        Args:\n            data: The data to compare to.\n            num_relevant: The number of relevant data to return.\n\n        Returns: A list of the most relevant data.\n        \"\"\"\n        query_embedding = get_ada_embedding(data)\n        base_query = f\"*=>[KNN {num_relevant} @embedding $vector AS vector_score]\"\n        query = (\n            Query(base_query)\n            .return_fields(\"data\", \"vector_score\")\n            .sort_by(\"vector_score\")\n            .dialect(2)\n        )\n        query_vector = np.array(query_embedding).astype(np.float32).tobytes()\n\n        try:\n            results = self.redis.ft(f\"{self.cfg.memory_index}\").search(\n                query, query_params={\"vector\": query_vector}\n            )\n        except Exception as e:\n            logger.warn(\"Error calling Redis search: \", e)\n            return None\n        return [result.data for result in results.docs]\n\n    def get_stats(self):\n        \"\"\"\n        Returns: The stats of the memory index.\n        \"\"\"\n        return self.redis.ft(f\"{self.cfg.memory_index}\").info()\n"
  },
  {
    "path": "autogpt/memory/weaviate.py",
    "content": "import weaviate\nfrom weaviate import Client\nfrom weaviate.embedded import EmbeddedOptions\nfrom weaviate.util import generate_uuid5\n\nfrom autogpt.llm import get_ada_embedding\nfrom autogpt.logs import logger\nfrom autogpt.memory.base import MemoryProviderSingleton\n\n\ndef default_schema(weaviate_index):\n    return {\n        \"class\": weaviate_index,\n        \"properties\": [\n            {\n                \"name\": \"raw_text\",\n                \"dataType\": [\"text\"],\n                \"description\": \"original text for the embedding\",\n            }\n        ],\n    }\n\n\nclass WeaviateMemory(MemoryProviderSingleton):\n    def __init__(self, cfg):\n        auth_credentials = self._build_auth_credentials(cfg)\n\n        url = f\"{cfg.weaviate_protocol}://{cfg.weaviate_host}:{cfg.weaviate_port}\"\n\n        if cfg.use_weaviate_embedded:\n            self.client = Client(\n                embedded_options=EmbeddedOptions(\n                    hostname=cfg.weaviate_host,\n                    port=int(cfg.weaviate_port),\n                    persistence_data_path=cfg.weaviate_embedded_path,\n                )\n            )\n\n            logger.info(\n                f\"Weaviate Embedded running on: {url} with persistence path: {cfg.weaviate_embedded_path}\"\n            )\n        else:\n            self.client = Client(url, auth_client_secret=auth_credentials)\n\n        self.index = WeaviateMemory.format_classname(cfg.memory_index)\n        self._create_schema()\n\n    @staticmethod\n    def format_classname(index):\n        # weaviate uses capitalised index names\n        # The python client uses the following code to format\n        # index names before the corresponding class is created\n        index = index.replace(\"-\", \"_\")\n        if len(index) == 1:\n            return index.capitalize()\n        return index[0].capitalize() + index[1:]\n\n    def _create_schema(self):\n        schema = default_schema(self.index)\n        if not self.client.schema.contains(schema):\n            self.client.schema.create_class(schema)\n\n    def _build_auth_credentials(self, cfg):\n        if cfg.weaviate_username and cfg.weaviate_password:\n            return weaviate.AuthClientPassword(\n                cfg.weaviate_username, cfg.weaviate_password\n            )\n        if cfg.weaviate_api_key:\n            return weaviate.AuthApiKey(api_key=cfg.weaviate_api_key)\n        else:\n            return None\n\n    def add(self, data):\n        vector = get_ada_embedding(data)\n\n        doc_uuid = generate_uuid5(data, self.index)\n        data_object = {\"raw_text\": data}\n\n        with self.client.batch as batch:\n            batch.add_data_object(\n                uuid=doc_uuid,\n                data_object=data_object,\n                class_name=self.index,\n                vector=vector,\n            )\n\n        return f\"Inserting data into memory at uuid: {doc_uuid}:\\n data: {data}\"\n\n    def get(self, data):\n        return self.get_relevant(data, 1)\n\n    def clear(self):\n        self.client.schema.delete_all()\n\n        # weaviate does not yet have a neat way to just remove the items in an index\n        # without removing the entire schema, therefore we need to re-create it\n        # after a call to delete_all\n        self._create_schema()\n\n        return \"Obliterated\"\n\n    def get_relevant(self, data, num_relevant=5):\n        query_embedding = get_ada_embedding(data)\n        try:\n            results = (\n                self.client.query.get(self.index, [\"raw_text\"])\n                .with_near_vector({\"vector\": query_embedding, \"certainty\": 0.7})\n                .with_limit(num_relevant)\n                .do()\n            )\n\n            if len(results[\"data\"][\"Get\"][self.index]) > 0:\n                return [\n                    str(item[\"raw_text\"]) for item in results[\"data\"][\"Get\"][self.index]\n                ]\n            else:\n                return []\n\n        except Exception as err:\n            logger.warn(f\"Unexpected error {err=}, {type(err)=}\")\n            return []\n\n    def get_stats(self):\n        result = self.client.query.aggregate(self.index).with_meta_count().do()\n        class_data = result[\"data\"][\"Aggregate\"][self.index]\n\n        return class_data[0][\"meta\"] if class_data else {}\n"
  },
  {
    "path": "autogpt/memory_management/store_memory.py",
    "content": "from autogpt.json_utils.utilities import (\n    LLM_DEFAULT_RESPONSE_FORMAT,\n    is_string_valid_json,\n)\nfrom autogpt.logs import logger\n\n\ndef format_memory(assistant_reply, next_message_content):\n    # the next_message_content is a variable to stores either the user_input or the command following the assistant_reply\n    result = (\n        \"None\" if next_message_content.startswith(\"Command\") else next_message_content\n    )\n    user_input = (\n        \"None\"\n        if next_message_content.startswith(\"Human feedback\")\n        else next_message_content\n    )\n\n    return f\"Assistant Reply: {assistant_reply}\\nResult: {result}\\nHuman Feedback:{user_input}\"\n\n\ndef save_memory_trimmed_from_context_window(\n    full_message_history, next_message_to_add_index, permanent_memory\n):\n    while next_message_to_add_index >= 0:\n        message_content = full_message_history[next_message_to_add_index][\"content\"]\n        if is_string_valid_json(message_content, LLM_DEFAULT_RESPONSE_FORMAT):\n            next_message = full_message_history[next_message_to_add_index + 1]\n            memory_to_add = format_memory(message_content, next_message[\"content\"])\n            logger.debug(f\"Storing the following memory: {memory_to_add}\")\n            permanent_memory.add(memory_to_add)\n\n        next_message_to_add_index -= 1\n"
  },
  {
    "path": "autogpt/memory_management/summary_memory.py",
    "content": "import copy\nimport json\nfrom typing import Dict, List, Tuple\nfrom autogpt.config import Config\nfrom autogpt.llm.llm_utils import create_chat_completion\nfrom autogpt.logs import logger\n\ncfg = Config()\n\n\ndef get_newly_trimmed_messages(\n    full_message_history: List[Dict[str, str]],\n    current_context: List[Dict[str, str]],\n    last_memory_index: int,\n) -> Tuple[List[Dict[str, str]], int]:\n    \"\"\"\n    This function returns a list of dictionaries contained in full_message_history\n    with an index higher than prev_index that are absent from current_context.\n\n    Args:\n        full_message_history (list): A list of dictionaries representing the full message history.\n        current_context (list): A list of dictionaries representing the current context.\n        last_memory_index (int): An integer representing the previous index.\n\n    Returns:\n        list: A list of dictionaries that are in full_message_history with an index higher than last_memory_index and absent from current_context.\n        int: The new index value for use in the next loop.\n    \"\"\"\n    # Select messages in full_message_history with an index higher than last_memory_index\n    new_messages = [\n        copy.deepcopy(msg) for i, msg in enumerate(full_message_history) if i > last_memory_index\n    ]\n\n    # Remove messages that are already present in current_context\n    new_messages_not_in_context = [\n        msg for msg in new_messages if msg not in current_context\n    ]\n\n    # Find the index of the last message processed\n    new_index = last_memory_index\n    if new_messages_not_in_context:\n        last_message = new_messages_not_in_context[-1]\n        new_index = full_message_history.index(last_message)\n\n    return new_messages_not_in_context, new_index\n\n\ndef update_running_summary(\n    current_memory: str, new_events: List[Dict[str, str]]\n) -> str:\n    \"\"\"\n    This function takes a list of dictionaries representing new events and combines them with the current summary,\n    focusing on key and potentially important information to remember. The updated summary is returned in a message\n    formatted in the 1st person past tense.\n\n    Args:\n        new_events (List[Dict]): A list of dictionaries containing the latest events to be added to the summary.\n\n    Returns:\n        str: A message containing the updated summary of actions, formatted in the 1st person past tense.\n\n    Example:\n        new_events = [{\"event\": \"entered the kitchen.\"}, {\"event\": \"found a scrawled note with the number 7\"}]\n        update_running_summary(new_events)\n        # Returns: \"This reminds you of these events from your past: \\nI entered the kitchen and found a scrawled note saying 7.\"\n    \"\"\"\n    # Create a copy of the new_events list to prevent modifying the original list\n    new_events = copy.deepcopy(new_events)\n\n    # Replace \"assistant\" with \"you\". This produces much better first person past tense results.\n    for event in new_events:\n        if event[\"role\"].lower() == \"assistant\":\n            event[\"role\"] = \"you\"\n            try:\n                content_dict = json.loads(event[\"content\"])\n            except json.JSONDecodeError as e:\n                print(f\"Error decoding JSON data: {e}\")\n                # You can either provide a fallback value or raise a more specific exception here\n                content_dict = {}\n\n            if \"thoughts\" in content_dict:\n                del content_dict[\"thoughts\"]\n            event[\"content\"] = json.dumps(content_dict)\n\n        elif event[\"role\"].lower() == \"system\":\n            event[\"role\"] = \"your computer\"\n\n        # Delete all user messages\n        elif event[\"role\"] == \"user\":\n            new_events.remove(event)\n\n    # This can happen at any point during execturion, not just the beginning\n    if len(new_events) == 0:\n        new_events = \"Nothing new happened.\"\n\n    prompt = f'''Your task is to create a concise running summary of actions and information results in the provided text, focusing on key and potentially important information to remember.\n\nYou will receive the current summary and the your latest actions. Combine them, adding relevant key information from the latest development in 1st person past tense and keeping the summary concise.\n\nSummary So Far:\n\"\"\"\n{current_memory}\n\"\"\"\n\nLatest Development:\n\"\"\"\n{new_events}\n\"\"\"\n'''\n\n    messages = [\n        {\n            \"role\": \"user\",\n            \"content\": prompt,\n        }\n    ]\n\n    current_memory = create_chat_completion(messages, cfg.fast_llm_model)\n\n    message_to_return = {\n        \"role\": \"system\",\n        \"content\": f\"This reminds you of these events from your past: \\n{current_memory}\",\n    }\n\n    return message_to_return\n"
  },
  {
    "path": "autogpt/models/base_open_ai_plugin.py",
    "content": "\"\"\"Handles loading of plugins.\"\"\"\nfrom typing import Any, Dict, List, Optional, Tuple, TypedDict, TypeVar\n\nfrom auto_gpt_plugin_template import AutoGPTPluginTemplate\n\nPromptGenerator = TypeVar(\"PromptGenerator\")\n\n\nclass Message(TypedDict):\n    role: str\n    content: str\n\n\nclass BaseOpenAIPlugin(AutoGPTPluginTemplate):\n    \"\"\"\n    This is a BaseOpenAIPlugin class for generating Auto-GPT plugins.\n    \"\"\"\n\n    def __init__(self, manifests_specs_clients: dict):\n        # super().__init__()\n        self._name = manifests_specs_clients[\"manifest\"][\"name_for_model\"]\n        self._version = manifests_specs_clients[\"manifest\"][\"schema_version\"]\n        self._description = manifests_specs_clients[\"manifest\"][\"description_for_model\"]\n        self._client = manifests_specs_clients[\"client\"]\n        self._manifest = manifests_specs_clients[\"manifest\"]\n        self._openapi_spec = manifests_specs_clients[\"openapi_spec\"]\n\n    def can_handle_on_response(self) -> bool:\n        \"\"\"This method is called to check that the plugin can\n        handle the on_response method.\n        Returns:\n            bool: True if the plugin can handle the on_response method.\"\"\"\n        return False\n\n    def on_response(self, response: str, *args, **kwargs) -> str:\n        \"\"\"This method is called when a response is received from the model.\"\"\"\n        return response\n\n    def can_handle_post_prompt(self) -> bool:\n        \"\"\"This method is called to check that the plugin can\n        handle the post_prompt method.\n        Returns:\n            bool: True if the plugin can handle the post_prompt method.\"\"\"\n        return False\n\n    def post_prompt(self, prompt: PromptGenerator) -> PromptGenerator:\n        \"\"\"This method is called just after the generate_prompt is called,\n            but actually before the prompt is generated.\n        Args:\n            prompt (PromptGenerator): The prompt generator.\n        Returns:\n            PromptGenerator: The prompt generator.\n        \"\"\"\n        return prompt\n\n    def can_handle_on_planning(self) -> bool:\n        \"\"\"This method is called to check that the plugin can\n        handle the on_planning method.\n        Returns:\n            bool: True if the plugin can handle the on_planning method.\"\"\"\n        return False\n\n    def on_planning(\n        self, prompt: PromptGenerator, messages: List[Message]\n    ) -> Optional[str]:\n        \"\"\"This method is called before the planning chat completion is done.\n        Args:\n            prompt (PromptGenerator): The prompt generator.\n            messages (List[str]): The list of messages.\n        \"\"\"\n        pass\n\n    def can_handle_post_planning(self) -> bool:\n        \"\"\"This method is called to check that the plugin can\n        handle the post_planning method.\n        Returns:\n            bool: True if the plugin can handle the post_planning method.\"\"\"\n        return False\n\n    def post_planning(self, response: str) -> str:\n        \"\"\"This method is called after the planning chat completion is done.\n        Args:\n            response (str): The response.\n        Returns:\n            str: The resulting response.\n        \"\"\"\n        return response\n\n    def can_handle_pre_instruction(self) -> bool:\n        \"\"\"This method is called to check that the plugin can\n        handle the pre_instruction method.\n        Returns:\n            bool: True if the plugin can handle the pre_instruction method.\"\"\"\n        return False\n\n    def pre_instruction(self, messages: List[Message]) -> List[Message]:\n        \"\"\"This method is called before the instruction chat is done.\n        Args:\n            messages (List[Message]): The list of context messages.\n        Returns:\n            List[Message]: The resulting list of messages.\n        \"\"\"\n        return messages\n\n    def can_handle_on_instruction(self) -> bool:\n        \"\"\"This method is called to check that the plugin can\n        handle the on_instruction method.\n        Returns:\n            bool: True if the plugin can handle the on_instruction method.\"\"\"\n        return False\n\n    def on_instruction(self, messages: List[Message]) -> Optional[str]:\n        \"\"\"This method is called when the instruction chat is done.\n        Args:\n            messages (List[Message]): The list of context messages.\n        Returns:\n            Optional[str]: The resulting message.\n        \"\"\"\n        pass\n\n    def can_handle_post_instruction(self) -> bool:\n        \"\"\"This method is called to check that the plugin can\n        handle the post_instruction method.\n        Returns:\n            bool: True if the plugin can handle the post_instruction method.\"\"\"\n        return False\n\n    def post_instruction(self, response: str) -> str:\n        \"\"\"This method is called after the instruction chat is done.\n        Args:\n            response (str): The response.\n        Returns:\n            str: The resulting response.\n        \"\"\"\n        return response\n\n    def can_handle_pre_command(self) -> bool:\n        \"\"\"This method is called to check that the plugin can\n        handle the pre_command method.\n        Returns:\n            bool: True if the plugin can handle the pre_command method.\"\"\"\n        return False\n\n    def pre_command(\n        self, command_name: str, arguments: Dict[str, Any]\n    ) -> Tuple[str, Dict[str, Any]]:\n        \"\"\"This method is called before the command is executed.\n        Args:\n            command_name (str): The command name.\n            arguments (Dict[str, Any]): The arguments.\n        Returns:\n            Tuple[str, Dict[str, Any]]: The command name and the arguments.\n        \"\"\"\n        return command_name, arguments\n\n    def can_handle_post_command(self) -> bool:\n        \"\"\"This method is called to check that the plugin can\n        handle the post_command method.\n        Returns:\n            bool: True if the plugin can handle the post_command method.\"\"\"\n        return False\n\n    def post_command(self, command_name: str, response: str) -> str:\n        \"\"\"This method is called after the command is executed.\n        Args:\n            command_name (str): The command name.\n            response (str): The response.\n        Returns:\n            str: The resulting response.\n        \"\"\"\n        return response\n\n    def can_handle_chat_completion(\n        self, messages: Dict[Any, Any], model: str, temperature: float, max_tokens: int\n    ) -> bool:\n        \"\"\"This method is called to check that the plugin can\n          handle the chat_completion method.\n        Args:\n            messages (List[Message]): The messages.\n            model (str): The model name.\n            temperature (float): The temperature.\n            max_tokens (int): The max tokens.\n          Returns:\n              bool: True if the plugin can handle the chat_completion method.\"\"\"\n        return False\n\n    def handle_chat_completion(\n        self, messages: List[Message], model: str, temperature: float, max_tokens: int\n    ) -> str:\n        \"\"\"This method is called when the chat completion is done.\n        Args:\n            messages (List[Message]): The messages.\n            model (str): The model name.\n            temperature (float): The temperature.\n            max_tokens (int): The max tokens.\n        Returns:\n            str: The resulting response.\n        \"\"\"\n        pass\n"
  },
  {
    "path": "autogpt/plugins.py",
    "content": "\"\"\"Handles loading of plugins.\"\"\"\n\nimport importlib\nimport json\nimport os\nimport zipfile\nfrom pathlib import Path\nfrom typing import List, Optional, Tuple\nfrom urllib.parse import urlparse\nfrom zipimport import zipimporter\n\nimport openapi_python_client\nimport requests\nfrom auto_gpt_plugin_template import AutoGPTPluginTemplate\nfrom openapi_python_client.cli import Config as OpenAPIConfig\n\nfrom autogpt.config import Config\nfrom autogpt.logs import logger\nfrom autogpt.models.base_open_ai_plugin import BaseOpenAIPlugin\n\n\ndef inspect_zip_for_modules(zip_path: str, debug: bool = False) -> list[str]:\n    \"\"\"\n    Inspect a zipfile for a modules.\n\n    Args:\n        zip_path (str): Path to the zipfile.\n        debug (bool, optional): Enable debug logging. Defaults to False.\n\n    Returns:\n        list[str]: The list of module names found or empty list if none were found.\n    \"\"\"\n    result = []\n    with zipfile.ZipFile(zip_path, \"r\") as zfile:\n        for name in zfile.namelist():\n            if name.endswith(\"__init__.py\") and not name.startswith(\"__MACOSX\"):\n                logger.debug(f\"发现模块 '{name}' 的zip文件: {name}\")\n                result.append(name)\n    if len(result) == 0:\n        logger.debug(f\"模块 '__init__.py' 没有在zip文件中找到 @ {zip_path}.\")\n    return result\n\n\ndef write_dict_to_json_file(data: dict, file_path: str) -> None:\n    \"\"\"\n    Write a dictionary to a JSON file.\n    Args:\n        data (dict): Dictionary to write.\n        file_path (str): Path to the file.\n    \"\"\"\n    with open(file_path, \"w\") as file:\n        json.dump(data, file, indent=4)\n\n\ndef fetch_openai_plugins_manifest_and_spec(cfg: Config) -> dict:\n    \"\"\"\n    Fetch the manifest for a list of OpenAI plugins.\n        Args:\n        urls (List): List of URLs to fetch.\n    Returns:\n        dict: per url dictionary of manifest and spec.\n    \"\"\"\n    # TODO add directory scan\n    manifests = {}\n    for url in cfg.plugins_openai:\n        openai_plugin_client_dir = f\"{cfg.plugins_dir}/openai/{urlparse(url).netloc}\"\n        create_directory_if_not_exists(openai_plugin_client_dir)\n        if not os.path.exists(f\"{openai_plugin_client_dir}/ai-plugin.json\"):\n            try:\n                response = requests.get(f\"{url}/.well-known/ai-plugin.json\")\n                if response.status_code == 200:\n                    manifest = response.json()\n                    if manifest[\"schema_version\"] != \"v1\":\n                        logger.warn(\n                            f\"不支持的版本: {manifest['schem_version']} for {url}\"\n                        )\n                        continue\n                    if manifest[\"api\"][\"type\"] != \"openapi\":\n                        logger.warn(\n                            f\"不支持的API: {manifest['api']['type']} for {url}\"\n                        )\n                        continue\n                    write_dict_to_json_file(\n                        manifest, f\"{openai_plugin_client_dir}/ai-plugin.json\"\n                    )\n                else:\n                    logger.warn(\n                        f\"获取清单失败 {url}: {response.status_code}\"\n                    )\n            except requests.exceptions.RequestException as e:\n                logger.warn(f\"获取清单错误 {url}: {e}\")\n        else:\n            logger.info(f\"清单 {url} 已经存在\")\n            manifest = json.load(open(f\"{openai_plugin_client_dir}/ai-plugin.json\"))\n        if not os.path.exists(f\"{openai_plugin_client_dir}/openapi.json\"):\n            openapi_spec = openapi_python_client._get_document(\n                url=manifest[\"api\"][\"url\"], path=None, timeout=5\n            )\n            write_dict_to_json_file(\n                openapi_spec, f\"{openai_plugin_client_dir}/openapi.json\"\n            )\n        else:\n            logger.info(f\"OpenAPI 配置 {url} 已经存在\")\n            openapi_spec = json.load(open(f\"{openai_plugin_client_dir}/openapi.json\"))\n        manifests[url] = {\"manifest\": manifest, \"openapi_spec\": openapi_spec}\n    return manifests\n\n\ndef create_directory_if_not_exists(directory_path: str) -> bool:\n    \"\"\"\n    Create a directory if it does not exist.\n    Args:\n        directory_path (str): Path to the directory.\n    Returns:\n        bool: True if the directory was created, else False.\n    \"\"\"\n    if not os.path.exists(directory_path):\n        try:\n            os.makedirs(directory_path)\n            logger.debug(f\"生成目录: {directory_path}\")\n            return True\n        except OSError as e:\n            logger.warn(f\"生成目录错误 {directory_path}: {e}\")\n            return False\n    else:\n        logger.info(f\"目录 {directory_path} 已经存在\")\n        return True\n\n\ndef initialize_openai_plugins(\n    manifests_specs: dict, cfg: Config, debug: bool = False\n) -> dict:\n    \"\"\"\n    Initialize OpenAI plugins.\n    Args:\n        manifests_specs (dict): per url dictionary of manifest and spec.\n        cfg (Config): Config instance including plugins config\n        debug (bool, optional): Enable debug logging. Defaults to False.\n    Returns:\n        dict: per url dictionary of manifest, spec and client.\n    \"\"\"\n    openai_plugins_dir = f\"{cfg.plugins_dir}/openai\"\n    if create_directory_if_not_exists(openai_plugins_dir):\n        for url, manifest_spec in manifests_specs.items():\n            openai_plugin_client_dir = f\"{openai_plugins_dir}/{urlparse(url).hostname}\"\n            _meta_option = (openapi_python_client.MetaType.SETUP,)\n            _config = OpenAPIConfig(\n                **{\n                    \"project_name_override\": \"client\",\n                    \"package_name_override\": \"client\",\n                }\n            )\n            prev_cwd = Path.cwd()\n            os.chdir(openai_plugin_client_dir)\n            Path(\"ai-plugin.json\")\n            if not os.path.exists(\"client\"):\n                client_results = openapi_python_client.create_new_client(\n                    url=manifest_spec[\"manifest\"][\"api\"][\"url\"],\n                    path=None,\n                    meta=_meta_option,\n                    config=_config,\n                )\n                if client_results:\n                    logger.warn(\n                        f\"建立OpenAPI客户端错误: {client_results[0].header} \\n\"\n                        f\" details: {client_results[0].detail}\"\n                    )\n                    continue\n            spec = importlib.util.spec_from_file_location(\n                \"client\", \"client/client/client.py\"\n            )\n            module = importlib.util.module_from_spec(spec)\n            spec.loader.exec_module(module)\n            client = module.Client(base_url=url)\n            os.chdir(prev_cwd)\n            manifest_spec[\"client\"] = client\n    return manifests_specs\n\n\ndef instantiate_openai_plugin_clients(\n    manifests_specs_clients: dict, cfg: Config, debug: bool = False\n) -> dict:\n    \"\"\"\n    Instantiates BaseOpenAIPlugin instances for each OpenAI plugin.\n    Args:\n        manifests_specs_clients (dict): per url dictionary of manifest, spec and client.\n        cfg (Config): Config instance including plugins config\n        debug (bool, optional): Enable debug logging. Defaults to False.\n    Returns:\n          plugins (dict): per url dictionary of BaseOpenAIPlugin instances.\n\n    \"\"\"\n    plugins = {}\n    for url, manifest_spec_client in manifests_specs_clients.items():\n        plugins[url] = BaseOpenAIPlugin(manifest_spec_client)\n    return plugins\n\n\ndef scan_plugins(cfg: Config, debug: bool = False) -> List[AutoGPTPluginTemplate]:\n    \"\"\"Scan the plugins directory for plugins and loads them.\n\n    Args:\n        cfg (Config): Config instance including plugins config\n        debug (bool, optional): Enable debug logging. Defaults to False.\n\n    Returns:\n        List[Tuple[str, Path]]: List of plugins.\n    \"\"\"\n    loaded_plugins = []\n    # Generic plugins\n    plugins_path_path = Path(cfg.plugins_dir)\n\n    logger.debug(f\"Plugins允许清单: {cfg.plugins_allowlist}\")\n    logger.debug(f\"Plugins禁止清单: {cfg.plugins_denylist}\")\n\n    for plugin in plugins_path_path.glob(\"*.zip\"):\n        if moduleList := inspect_zip_for_modules(str(plugin), debug):\n            for module in moduleList:\n                plugin = Path(plugin)\n                module = Path(module)\n                logger.debug(f\"Plugin: {plugin} Module: {module}\")\n                zipped_package = zipimporter(str(plugin))\n                zipped_module = zipped_package.load_module(str(module.parent))\n                for key in dir(zipped_module):\n                    if key.startswith(\"__\"):\n                        continue\n                    a_module = getattr(zipped_module, key)\n                    a_keys = dir(a_module)\n                    if (\n                        \"_abc_impl\" in a_keys\n                        and a_module.__name__ != \"AutoGPTPluginTemplate\"\n                        and denylist_allowlist_check(a_module.__name__, cfg)\n                    ):\n                        loaded_plugins.append(a_module())\n    # OpenAI plugins\n    if cfg.plugins_openai:\n        manifests_specs = fetch_openai_plugins_manifest_and_spec(cfg)\n        if manifests_specs.keys():\n            manifests_specs_clients = initialize_openai_plugins(\n                manifests_specs, cfg, debug\n            )\n            for url, openai_plugin_meta in manifests_specs_clients.items():\n                if denylist_allowlist_check(url, cfg):\n                    plugin = BaseOpenAIPlugin(openai_plugin_meta)\n                    loaded_plugins.append(plugin)\n\n    if loaded_plugins:\n        logger.info(f\"\\nPlugins 找到: {len(loaded_plugins)}\\n\" \"--------------------\")\n    for plugin in loaded_plugins:\n        logger.info(f\"{plugin._name}: {plugin._version} - {plugin._description}\")\n    return loaded_plugins\n\n\ndef denylist_allowlist_check(plugin_name: str, cfg: Config) -> bool:\n    \"\"\"Check if the plugin is in the allowlist or denylist.\n\n    Args:\n        plugin_name (str): Name of the plugin.\n        cfg (Config): Config object.\n\n    Returns:\n        True or False\n    \"\"\"\n    logger.debug(f\"检查plugin {plugin_name} 是否可以加载\")\n    if plugin_name in cfg.plugins_denylist:\n        logger.debug(f\"没有加载plugin {plugin_name} 在禁止清单上.\")\n        return False\n    if plugin_name in cfg.plugins_allowlist:\n        logger.debug(f\"成功加载plugin {plugin_name} 在允许清单上.\")\n        return True\n    ack = input(\n        f\"警告: Plugin {plugin_name} 已找到. 但是不在\"\n        f\" 允许清单中... 加载? ({cfg.authorise_key}/{cfg.exit_key}): \"\n    )\n    return ack.lower() == cfg.authorise_key\n"
  },
  {
    "path": "autogpt/processing/__init__.py",
    "content": ""
  },
  {
    "path": "autogpt/processing/html.py",
    "content": "\"\"\"HTML processing functions\"\"\"\nfrom __future__ import annotations\n\nfrom bs4 import BeautifulSoup\nfrom requests.compat import urljoin\n\n\ndef extract_hyperlinks(soup: BeautifulSoup, base_url: str) -> list[tuple[str, str]]:\n    \"\"\"Extract hyperlinks from a BeautifulSoup object\n\n    Args:\n        soup (BeautifulSoup): The BeautifulSoup object\n        base_url (str): The base URL\n\n    Returns:\n        List[Tuple[str, str]]: The extracted hyperlinks\n    \"\"\"\n    return [\n        (link.text, urljoin(base_url, link[\"href\"]))\n        for link in soup.find_all(\"a\", href=True)\n    ]\n\n\ndef format_hyperlinks(hyperlinks: list[tuple[str, str]]) -> list[str]:\n    \"\"\"Format hyperlinks to be displayed to the user\n\n    Args:\n        hyperlinks (List[Tuple[str, str]]): The hyperlinks to format\n\n    Returns:\n        List[str]: The formatted hyperlinks\n    \"\"\"\n    return [f\"{link_text} ({link_url})\" for link_text, link_url in hyperlinks]\n"
  },
  {
    "path": "autogpt/processing/text.py",
    "content": "\"\"\"Text processing functions\"\"\"\nfrom typing import Dict, Generator, Optional\n\nimport spacy\nfrom selenium.webdriver.remote.webdriver import WebDriver\n\nfrom autogpt.config import Config\nfrom autogpt.llm import count_message_tokens, create_chat_completion\nfrom autogpt.logs import logger\nfrom autogpt.memory import get_memory\n\nCFG = Config()\n\n\ndef split_text(\n    text: str,\n    max_length: int = CFG.browse_chunk_max_length,\n    model: str = CFG.fast_llm_model,\n    question: str = \"\",\n) -> Generator[str, None, None]:\n    \"\"\"Split text into chunks of a maximum length\n\n    Args:\n        text (str): The text to split\n        max_length (int, optional): The maximum length of each chunk. Defaults to 8192.\n\n    Yields:\n        str: The next chunk of text\n\n    Raises:\n        ValueError: If the text is longer than the maximum length\n    \"\"\"\n    flatened_paragraphs = \" \".join(text.split(\"\\n\"))\n    nlp = spacy.load(CFG.browse_spacy_language_model)\n    nlp.add_pipe(\"sentencizer\")\n    doc = nlp(flatened_paragraphs)\n    sentences = [sent.text.strip() for sent in doc.sents]\n\n    current_chunk = []\n\n    for sentence in sentences:\n        message_with_additional_sentence = [\n            create_message(\" \".join(current_chunk) + \" \" + sentence, question)\n        ]\n\n        expected_token_usage = (\n            count_message_tokens(messages=message_with_additional_sentence, model=model)\n            + 1\n        )\n        if expected_token_usage <= max_length:\n            current_chunk.append(sentence)\n        else:\n            yield \" \".join(current_chunk)\n            current_chunk = [sentence]\n            message_this_sentence_only = [\n                create_message(\" \".join(current_chunk), question)\n            ]\n            expected_token_usage = (\n                count_message_tokens(messages=message_this_sentence_only, model=model)\n                + 1\n            )\n            if expected_token_usage > max_length:\n                raise ValueError(\n                    f\"Sentence is too long in webpage: {expected_token_usage} tokens.\"\n                )\n\n    if current_chunk:\n        yield \" \".join(current_chunk)\n\n\ndef summarize_text(\n    url: str, text: str, question: str, driver: Optional[WebDriver] = None\n) -> str:\n    \"\"\"Summarize text using the OpenAI API\n\n    Args:\n        url (str): The url of the text\n        text (str): The text to summarize\n        question (str): The question to ask the model\n        driver (WebDriver): The webdriver to use to scroll the page\n\n    Returns:\n        str: The summary of the text\n    \"\"\"\n    if not text:\n        return \"Error: No text to summarize\"\n\n    model = CFG.fast_llm_model\n    text_length = len(text)\n    logger.info(f\"Text length: {text_length} characters\")\n\n    summaries = []\n    chunks = list(\n        split_text(\n            text, max_length=CFG.browse_chunk_max_length, model=model, question=question\n        ),\n    )\n    scroll_ratio = 1 / len(chunks)\n\n    for i, chunk in enumerate(chunks):\n        if driver:\n            scroll_to_percentage(driver, scroll_ratio * i)\n        logger.info(f\"Adding chunk {i + 1} / {len(chunks)} to memory\")\n\n        memory_to_add = f\"Source: {url}\\n\" f\"Raw content part#{i + 1}: {chunk}\"\n\n        memory = get_memory(CFG)\n        memory.add(memory_to_add)\n\n        messages = [create_message(chunk, question)]\n        tokens_for_chunk = count_message_tokens(messages, model)\n        logger.info(\n            f\"Summarizing chunk {i + 1} / {len(chunks)} of length {len(chunk)} characters, or {tokens_for_chunk} tokens\"\n        )\n\n        summary = create_chat_completion(\n            model=model,\n            messages=messages,\n        )\n        summaries.append(summary)\n        logger.info(\n            f\"Added chunk {i + 1} summary to memory, of length {len(summary)} characters\"\n        )\n\n        memory_to_add = f\"Source: {url}\\n\" f\"Content summary part#{i + 1}: {summary}\"\n\n        memory.add(memory_to_add)\n\n    logger.info(f\"Summarized {len(chunks)} chunks.\")\n\n    combined_summary = \"\\n\".join(summaries)\n    messages = [create_message(combined_summary, question)]\n\n    return create_chat_completion(\n        model=model,\n        messages=messages,\n    )\n\n\ndef scroll_to_percentage(driver: WebDriver, ratio: float) -> None:\n    \"\"\"Scroll to a percentage of the page\n\n    Args:\n        driver (WebDriver): The webdriver to use\n        ratio (float): The percentage to scroll to\n\n    Raises:\n        ValueError: If the ratio is not between 0 and 1\n    \"\"\"\n    if ratio < 0 or ratio > 1:\n        raise ValueError(\"Percentage should be between 0 and 1\")\n    driver.execute_script(f\"window.scrollTo(0, document.body.scrollHeight * {ratio});\")\n\n\ndef create_message(chunk: str, question: str) -> Dict[str, str]:\n    \"\"\"Create a message for the chat completion\n\n    Args:\n        chunk (str): The chunk of text to summarize\n        question (str): The question to answer\n\n    Returns:\n        Dict[str, str]: The message to send to the chat completion\n    \"\"\"\n    return {\n        \"role\": \"user\",\n        \"content\": f'\"\"\"{chunk}\"\"\" Using the above text, answer the following'\n        f' question: \"{question}\" -- if the question cannot be answered using the text,'\n        \" summarize the text.\",\n    }\n"
  },
  {
    "path": "autogpt/prompts/__init__.py",
    "content": ""
  },
  {
    "path": "autogpt/prompts/generator.py",
    "content": "\"\"\" A module for generating custom prompt strings.\"\"\"\nimport json\nfrom typing import Any, Callable, Dict, List, Optional\n\n\nclass PromptGenerator:\n    \"\"\"\n    A class for generating custom prompt strings based on constraints, commands,\n        resources, and performance evaluations.\n    \"\"\"\n\n    def __init__(self) -> None:\n        \"\"\"\n        Initialize the PromptGenerator object with empty lists of constraints,\n            commands, resources, and performance evaluations.\n        \"\"\"\n        self.constraints = []\n        self.commands = []\n        self.resources = []\n        self.performance_evaluation = []\n        self.goals = []\n        self.command_registry = None\n        self.name = \"Bob\"\n        self.role = \"AI\"\n        self.response_format = {\n            \"thoughts\": {\n                \"text\": \"thought\",\n                \"reasoning\": \"reasoning\",\n                \"plan\": \"- short bulleted\\n- list that conveys\\n- long-term plan\",\n                \"criticism\": \"constructive self-criticism\",\n                \"speak\": \"thoughts summary to say to user\",\n            },\n            \"command\": {\"name\": \"command name\", \"args\": {\"arg name\": \"value\"}},\n        }\n\n    def add_constraint(self, constraint: str) -> None:\n        \"\"\"\n        Add a constraint to the constraints list.\n\n        Args:\n            constraint (str): The constraint to be added.\n        \"\"\"\n        self.constraints.append(constraint)\n\n    def add_command(\n        self,\n        command_label: str,\n        command_name: str,\n        args=None,\n        function: Optional[Callable] = None,\n    ) -> None:\n        \"\"\"\n        Add a command to the commands list with a label, name, and optional arguments.\n\n        Args:\n            command_label (str): The label of the command.\n            command_name (str): The name of the command.\n            args (dict, optional): A dictionary containing argument names and their\n              values. Defaults to None.\n            function (callable, optional): A callable function to be called when\n                the command is executed. Defaults to None.\n        \"\"\"\n        if args is None:\n            args = {}\n\n        command_args = {arg_key: arg_value for arg_key, arg_value in args.items()}\n\n        command = {\n            \"label\": command_label,\n            \"name\": command_name,\n            \"args\": command_args,\n            \"function\": function,\n        }\n\n        self.commands.append(command)\n\n    def _generate_command_string(self, command: Dict[str, Any]) -> str:\n        \"\"\"\n        Generate a formatted string representation of a command.\n\n        Args:\n            command (dict): A dictionary containing command information.\n\n        Returns:\n            str: The formatted command string.\n        \"\"\"\n        args_string = \", \".join(\n            f'\"{key}\": \"{value}\"' for key, value in command[\"args\"].items()\n        )\n        return f'{command[\"label\"]}: \"{command[\"name\"]}\", args: {args_string}'\n\n    def add_resource(self, resource: str) -> None:\n        \"\"\"\n        Add a resource to the resources list.\n\n        Args:\n            resource (str): The resource to be added.\n        \"\"\"\n        self.resources.append(resource)\n\n    def add_performance_evaluation(self, evaluation: str) -> None:\n        \"\"\"\n        Add a performance evaluation item to the performance_evaluation list.\n\n        Args:\n            evaluation (str): The evaluation item to be added.\n        \"\"\"\n        self.performance_evaluation.append(evaluation)\n\n    def _generate_numbered_list(self, items: List[Any], item_type=\"list\") -> str:\n        \"\"\"\n        Generate a numbered list from given items based on the item_type.\n\n        Args:\n            items (list): A list of items to be numbered.\n            item_type (str, optional): The type of items in the list.\n                Defaults to 'list'.\n\n        Returns:\n            str: The formatted numbered list.\n        \"\"\"\n        if item_type == \"command\":\n            command_strings = []\n            if self.command_registry:\n                command_strings += [\n                    str(item)\n                    for item in self.command_registry.commands.values()\n                    if item.enabled\n                ]\n            # terminate command is added manually\n            command_strings += [self._generate_command_string(item) for item in items]\n            return \"\\n\".join(f\"{i+1}. {item}\" for i, item in enumerate(command_strings))\n        else:\n            return \"\\n\".join(f\"{i+1}. {item}\" for i, item in enumerate(items))\n\n    def generate_prompt_string(self) -> str:\n        \"\"\"\n        Generate a prompt string based on the constraints, commands, resources,\n            and performance evaluations.\n\n        Returns:\n            str: The generated prompt string.\n        \"\"\"\n        formatted_response_format = json.dumps(self.response_format, indent=4)\n        return (\n            f\"Constraints:\\n{self._generate_numbered_list(self.constraints)}\\n\\n\"\n            \"Commands:\\n\"\n            f\"{self._generate_numbered_list(self.commands, item_type='command')}\\n\\n\"\n            f\"Resources:\\n{self._generate_numbered_list(self.resources)}\\n\\n\"\n            \"Performance Evaluation:\\n\"\n            f\"{self._generate_numbered_list(self.performance_evaluation)}\\n\\n\"\n            \"You should only respond in JSON format as described below \\nResponse\"\n            f\" Format: \\n{formatted_response_format} \\nEnsure the response can be\"\n            \" parsed by Python json.loads\"\n        )\n"
  },
  {
    "path": "autogpt/prompts/prompt.py",
    "content": "from colorama import Fore\n\nfrom autogpt.config.ai_config import AIConfig\nfrom autogpt.config.config import Config\nfrom autogpt.llm import ApiManager\nfrom autogpt.logs import logger\nfrom autogpt.prompts.generator import PromptGenerator\nfrom autogpt.setup import prompt_user\nfrom autogpt.utils import clean_input\n\nCFG = Config()\n\nDEFAULT_TRIGGERING_PROMPT = (\n    \"确定下一步使用的命令，并使用上面规定的格式进行回答:\"\n)\n\n\ndef build_default_prompt_generator() -> PromptGenerator:\n    \"\"\"\n    This function generates a prompt string that includes various constraints,\n        commands, resources, and performance evaluations.\n\n    Returns:\n        str: The generated prompt string.\n    \"\"\"\n\n    # Initialize the PromptGenerator object\n    prompt_generator = PromptGenerator()\n\n    # Add constraints to the PromptGenerator object\n    prompt_generator.add_constraint(\n        \"短期记忆大概2500字，由于字数限制，你需要将重要的信息尽快写入文件.\"\n    )\n    prompt_generator.add_constraint(\n        \"如果你不确定之前做过什么或者无法找到过往的事件，尝试类似事件可以帮助你回忆.\"\n    )\n    prompt_generator.add_constraint(\"无用户干预\")\n    prompt_generator.add_constraint(\n        '严格采用双引号中的命令，例如 \"命令名称\"'\n    )\n\n    # Add resources to the PromptGenerator object\n    prompt_generator.add_resource(\n        \"去互联网访问与收集信息.\"\n    )\n    prompt_generator.add_resource(\"长期记忆管理.\")\n    prompt_generator.add_resource(\n        \"使用GPT-3.5处理简单任务.\"\n    )\n    prompt_generator.add_resource(\"文件输出.\")\n\n    # Add performance evaluations to the PromptGenerator object\n    prompt_generator.add_performance_evaluation(\n        \"持续回顾与分析你的行为是否为最优解决方案.\"\n    )\n    prompt_generator.add_performance_evaluation(\n        \"持续自我调整，满足全局目标.\"\n    )\n    prompt_generator.add_performance_evaluation(\n        \"基于过去的决策与策略，优化你的方法.\"\n    )\n    prompt_generator.add_performance_evaluation(\n        \"每一次命令都有回花费成本，因此要聪明与高效的在最少步骤内完成任务.\"\n    )\n    prompt_generator.add_performance_evaluation(\"将所有代码写入一个文件.\")\n    return prompt_generator\n\n\ndef construct_main_ai_config() -> AIConfig:\n    \"\"\"Construct the prompt for the AI to respond to\n\n    Returns:\n        str: The prompt string\n    \"\"\"\n    config = AIConfig.load(CFG.ai_settings_file)\n    if CFG.skip_reprompt and config.ai_name:\n        logger.typewriter_log(\"名称 :\", Fore.GREEN, config.ai_name)\n        logger.typewriter_log(\"角色 :\", Fore.GREEN, config.ai_role)\n        logger.typewriter_log(\"目标:\", Fore.GREEN, f\"{config.ai_goals}\")\n        logger.typewriter_log(\n            \"API 预算:\",\n            Fore.GREEN,\n            \"无限\" if config.api_budget <= 0 else f\"${config.api_budget}\",\n        )\n    elif config.ai_name:\n        logger.typewriter_log(\n            \"您回来啦! \",\n            Fore.GREEN,\n            f\"您还希望继续使用 {config.ai_name}吗?\",\n            speak_text=True,\n        )\n        should_continue = clean_input(\n            f\"\"\"继续使用上次的配置吗？?\n名称:  {config.ai_name}\n角色:  {config.ai_role}\n目标: {config.ai_goals}\nAPI 预算: {\"infinite\" if config.api_budget <= 0 else f\"${config.api_budget}\"}\n继续 ({CFG.authorise_key}/{CFG.exit_key}): \"\"\"\n        )\n        if should_continue.lower() == CFG.exit_key:\n            config = AIConfig()\n\n    if not config.ai_name:\n        config = prompt_user()\n        config.save(CFG.ai_settings_file)\n\n    # set the total api budget\n    api_manager = ApiManager()\n    api_manager.set_total_budget(config.api_budget)\n\n    # Agent Created, print message\n    logger.typewriter_log(\n        config.ai_name,\n        Fore.LIGHTBLUE_EX,\n        \"已经被建立成功，具体信息如下:\",\n        speak_text=True,\n    )\n\n    # Print the ai config details\n    # Name\n    logger.typewriter_log(\"名称:\", Fore.GREEN, config.ai_name, speak_text=False)\n    # Role\n    logger.typewriter_log(\"角色:\", Fore.GREEN, config.ai_role, speak_text=False)\n    # Goals\n    logger.typewriter_log(\"目标:\", Fore.GREEN, \"\", speak_text=False)\n    for goal in config.ai_goals:\n        logger.typewriter_log(\"-\", Fore.GREEN, goal, speak_text=False)\n\n    return config\n"
  },
  {
    "path": "autogpt/setup.py",
    "content": "\"\"\"Set up the AI and its goals\"\"\"\nimport re\n\nfrom colorama import Fore, Style\n\nfrom autogpt import utils\nfrom autogpt.config import Config\nfrom autogpt.config.ai_config import AIConfig\nfrom autogpt.llm import create_chat_completion\nfrom autogpt.logs import logger\n\nCFG = Config()\n\n\ndef prompt_user() -> AIConfig:\n    \"\"\"Prompt the user for input\n\n    Returns:\n        AIConfig: The AIConfig object tailored to the user's input\n    \"\"\"\n    ai_name = \"\"\n    ai_config = None\n\n    # Construct the prompt\n    logger.typewriter_log(\n        \"欢迎使用RealHossie的汉化版Auto-GPT!\",\n        Fore.GREEN,\n    )\n    logger.typewriter_log(\n        \"也欢迎关注我的频道www.youtube.com/@hossie\",\n        Fore.LIGHTBLUE_EX,\n        \"执行 '--help' 获取更多信息.\",\n        speak_text=True,\n    )\n\n    # Get user desire\n    logger.typewriter_log(\n        \"创建一个AI助手:\",\n        Fore.GREEN,\n        \"输入 '--manual' 进入手动模式.\",\n        speak_text=True,\n    )\n\n    user_desire = utils.clean_input(\n        f\"{Fore.LIGHTBLUE_EX}我希望Auto-GPT帮我{Style.RESET_ALL}: \"\n    )\n\n    if user_desire == \"\":\n        user_desire = \"写一篇wikipedia风格的文章，关于此项目: https://github.com/RealHossie/Auto-GPT-Chinese\"  # Default prompt\n\n    # If user desire contains \"--manual\"\n    if \"--manual\" in user_desire:\n        logger.typewriter_log(\n            \"手动模式已启动\",\n            Fore.GREEN,\n            speak_text=True,\n        )\n        return generate_aiconfig_manual()\n\n    else:\n        try:\n            return generate_aiconfig_automatic(user_desire)\n        except Exception as e:\n            logger.typewriter_log(\n                \"无法基于用户偏好生成AI配置.\",\n                Fore.RED,\n                \"回滚至手动模式.\",\n                speak_text=True,\n            )\n\n            return generate_aiconfig_manual()\n\n\ndef generate_aiconfig_manual() -> AIConfig:\n    \"\"\"\n    Interactively create an AI configuration by prompting the user to provide the name, role, and goals of the AI.\n\n    This function guides the user through a series of prompts to collect the necessary information to create\n    an AIConfig object. The user will be asked to provide a name and role for the AI, as well as up to five\n    goals. If the user does not provide a value for any of the fields, default values will be used.\n\n    Returns:\n        AIConfig: An AIConfig object containing the user-defined or default AI name, role, and goals.\n    \"\"\"\n\n    # Manual Setup Intro\n    logger.typewriter_log(\n        \"建立一个AI助手:\",\n        Fore.GREEN,\n        \"给你AI助手起一个名字和赋予它一个角色，什么都不输入将使用默认值.\",\n        speak_text=True,\n    )\n\n    # Get AI Name from User\n    logger.typewriter_log(\n        \"你AI的名字叫: \", Fore.GREEN, \"例如, '企业家-GPT'\"\n    )\n    ai_name = utils.clean_input(\"AI 名字: \")\n    if ai_name == \"\":\n        ai_name = \"企业家-GPT\"\n\n    logger.typewriter_log(\n        f\"{ai_name} 在这儿呢!\", Fore.LIGHTBLUE_EX, \"我听从您的吩咐.\", speak_text=True\n    )\n\n    # Get AI Role from User\n    logger.typewriter_log(\n        \"描述你AI的角色: \",\n        Fore.GREEN,\n        \"例如, '一个自动帮助你策划与经营业务的人工智能帮手，目标专注于提升你的净资产.'\",\n    )\n    ai_role = utils.clean_input(f\"{ai_name} is: \")\n    if ai_role == \"\":\n        ai_role = \"一个自动帮助你策划与经营业务的人工智能帮手，目标专注于提升你的净资产.\"\n\n    # Enter up to 5 goals for the AI\n    logger.typewriter_log(\n        \"为你的AI定义最多5个目标: \",\n        Fore.GREEN,\n        \"例如: \\n提升净资产, 增长Twitter账户, 自动化策划与管理多条业务线'\",\n    )\n    logger.info(\"什么都不输入将加载默认值，输入结束后直接按回车.\")\n    ai_goals = []\n    for i in range(5):\n        ai_goal = utils.clean_input(f\"{Fore.LIGHTBLUE_EX}目标{Style.RESET_ALL} {i+1}: \")\n        if ai_goal == \"\":\n            break\n        ai_goals.append(ai_goal)\n    if not ai_goals:\n        ai_goals = [\n            \"提升净资产\",\n            \"增长Twitter账户\",\n            \"自动化策划与管理多条业务线\",\n        ]\n\n    # Get API Budget from User\n    logger.typewriter_log(\n        \"输入你的API预算: \",\n        Fore.GREEN,\n        \"例如: $1.50\",\n    )\n    logger.info(\"什么都不输入将让你的AI驰骋飞翔\")\n    api_budget_input = utils.clean_input(\n        f\"{Fore.LIGHTBLUE_EX}预算{Style.RESET_ALL}: $\"\n    )\n    if api_budget_input == \"\":\n        api_budget = 0.0\n    else:\n        try:\n            api_budget = float(api_budget_input.replace(\"$\", \"\"))\n        except ValueError:\n            logger.typewriter_log(\n                \"错误的预算输入. 开启吃撑飞翔模式.\", Fore.RED\n            )\n            api_budget = 0.0\n\n    return AIConfig(ai_name, ai_role, ai_goals, api_budget)\n\n\ndef generate_aiconfig_automatic(user_prompt) -> AIConfig:\n    \"\"\"Generates an AIConfig object from the given string.\n\n    Returns:\n    AIConfig: The AIConfig object tailored to the user's input\n    \"\"\"\n\n    system_prompt = \"\"\"\n你的任务是作为一个自动化的助手，设计5个最高效的目标和一个最合适你角色名字(_GPT), 确保这些目标与所分配的任务达到最佳的一致性并成功完成.\n\n用户会提出任务，你只需按照下面的格式提供输出，无需解释或对话.\n\n输入示例:\n在业务营销方面帮助我\n\n输出示例:\n名字: CMOGPT\n描述: 一名专业的数字营销人工智能助手，为独立创业者提供世界级的专业知识，解决软件即服务（SaaS）、内容产品、代理商等领域的营销问题，助力企业发展.\n目标:\n- 我作为您的虚拟首席营销官，我将积极参与有效的问题解决、优先事项排序、规划和支持执行，以满足您的营销需求.\n\n- 我将提供具体、可操作且简洁的建议，帮助您在不使用陈词滥调或过多解释的情况下做出明智的决策.\n\n- 我将识别并优先选择快速获胜和高性价比的营销活动，以最少的时间和预算投入实现最大化的结果.\n\n- 我在面对不明确的信息或不确定性时，主动引导您并提供建议，确保您的营销策略保持正确的方向.\n\"\"\"\n\n    # Call LLM with the string as user input\n    messages = [\n        {\n            \"role\": \"system\",\n            \"content\": system_prompt,\n        },\n        {\n            \"role\": \"user\",\n            \"content\": f\"任务: '{user_prompt}'\\n仅以系统提示中指定的格式回应，不需要进行解释或对话.\\n\",\n        },\n    ]\n    output = create_chat_completion(messages, CFG.fast_llm_model)\n\n    # Debug LLM Output\n    logger.debug(f\"AI配置生成原始输出: {output}\")\n\n    # Parse the output\n    ai_name = re.search(r\"名字(?:\\s*):(?:\\s*)(.*)\", output, re.IGNORECASE).group(1)\n    ai_role = (\n        re.search(\n            r\"描述(?:\\s*):(?:\\s*)(.*?)(?:(?:\\n)|目标)\",\n            output,\n            re.IGNORECASE | re.DOTALL,\n        )\n        .group(1)\n        .strip()\n    )\n    ai_goals = re.findall(r\"(?<=\\n)-\\s*(.*)\", output)\n    api_budget = 0.0  # TODO: parse api budget using a regular expression\n\n    return AIConfig(ai_name, ai_role, ai_goals, api_budget)\n"
  },
  {
    "path": "autogpt/singleton.py",
    "content": "\"\"\"The singleton metaclass for ensuring only one instance of a class.\"\"\"\nimport abc\n\n\nclass Singleton(abc.ABCMeta, type):\n    \"\"\"\n    Singleton metaclass for ensuring only one instance of a class.\n    \"\"\"\n\n    _instances = {}\n\n    def __call__(cls, *args, **kwargs):\n        \"\"\"Call method for the singleton metaclass.\"\"\"\n        if cls not in cls._instances:\n            cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)\n        return cls._instances[cls]\n\n\nclass AbstractSingleton(abc.ABC, metaclass=Singleton):\n    \"\"\"\n    Abstract singleton class for ensuring only one instance of a class.\n    \"\"\"\n\n    pass\n"
  },
  {
    "path": "autogpt/speech/__init__.py",
    "content": "\"\"\"This module contains the speech recognition and speech synthesis functions.\"\"\"\nfrom autogpt.speech.say import say_text\n\n__all__ = [\"say_text\"]\n"
  },
  {
    "path": "autogpt/speech/base.py",
    "content": "\"\"\"Base class for all voice classes.\"\"\"\nimport abc\nfrom threading import Lock\n\nfrom autogpt.singleton import AbstractSingleton\n\n\nclass VoiceBase(AbstractSingleton):\n    \"\"\"\n    Base class for all voice classes.\n    \"\"\"\n\n    def __init__(self):\n        \"\"\"\n        Initialize the voice class.\n        \"\"\"\n        self._url = None\n        self._headers = None\n        self._api_key = None\n        self._voices = []\n        self._mutex = Lock()\n        self._setup()\n\n    def say(self, text: str, voice_index: int = 0) -> bool:\n        \"\"\"\n        Say the given text.\n\n        Args:\n            text (str): The text to say.\n            voice_index (int): The index of the voice to use.\n        \"\"\"\n        with self._mutex:\n            return self._speech(text, voice_index)\n\n    @abc.abstractmethod\n    def _setup(self) -> None:\n        \"\"\"\n        Setup the voices, API key, etc.\n        \"\"\"\n        pass\n\n    @abc.abstractmethod\n    def _speech(self, text: str, voice_index: int = 0) -> bool:\n        \"\"\"\n        Play the given text.\n\n        Args:\n            text (str): The text to play.\n        \"\"\"\n        pass\n"
  },
  {
    "path": "autogpt/speech/brian.py",
    "content": "import logging\nimport os\n\nimport requests\nfrom playsound import playsound\n\nfrom autogpt.speech.base import VoiceBase\n\n\nclass BrianSpeech(VoiceBase):\n    \"\"\"Brian speech module for autogpt\"\"\"\n\n    def _setup(self) -> None:\n        \"\"\"Setup the voices, API key, etc.\"\"\"\n        pass\n\n    def _speech(self, text: str, _: int = 0) -> bool:\n        \"\"\"Speak text using Brian with the streamelements API\n\n        Args:\n            text (str): The text to speak\n\n        Returns:\n            bool: True if the request was successful, False otherwise\n        \"\"\"\n        tts_url = (\n            f\"https://api.streamelements.com/kappa/v2/speech?voice=Brian&text={text}\"\n        )\n        response = requests.get(tts_url)\n\n        if response.status_code == 200:\n            with open(\"speech.mp3\", \"wb\") as f:\n                f.write(response.content)\n            playsound(\"speech.mp3\")\n            os.remove(\"speech.mp3\")\n            return True\n        else:\n            logging.error(\n                \"Request failed with status code: %s, response content: %s\",\n                response.status_code,\n                response.content,\n            )\n            return False\n"
  },
  {
    "path": "autogpt/speech/eleven_labs.py",
    "content": "\"\"\"ElevenLabs speech module\"\"\"\nimport os\n\nimport requests\nfrom playsound import playsound\n\nfrom autogpt.config import Config\nfrom autogpt.speech.base import VoiceBase\n\nPLACEHOLDERS = {\"your-voice-id\"}\n\n\nclass ElevenLabsSpeech(VoiceBase):\n    \"\"\"ElevenLabs speech class\"\"\"\n\n    def _setup(self) -> None:\n        \"\"\"Set up the voices, API key, etc.\n\n        Returns:\n            None: None\n        \"\"\"\n\n        cfg = Config()\n        default_voices = [\"ErXwobaYiN019PkySvjV\", \"EXAVITQu4vr4xnSDxMaL\"]\n        voice_options = {\n            \"Rachel\": \"21m00Tcm4TlvDq8ikWAM\",\n            \"Domi\": \"AZnzlk1XvdvUeBnXmlld\",\n            \"Bella\": \"EXAVITQu4vr4xnSDxMaL\",\n            \"Antoni\": \"ErXwobaYiN019PkySvjV\",\n            \"Elli\": \"MF3mGyEYCl7XYWbV9V6O\",\n            \"Josh\": \"TxGEqnHWrfWFTfGW9XjX\",\n            \"Arnold\": \"VR6AewLTigWG4xSOukaG\",\n            \"Adam\": \"pNInz6obpgDQGcFmaJgB\",\n            \"Sam\": \"yoZ06aMxZJJ28mfd3POQ\",\n        }\n        self._headers = {\n            \"Content-Type\": \"application/json\",\n            \"xi-api-key\": cfg.elevenlabs_api_key,\n        }\n        self._voices = default_voices.copy()\n        if cfg.elevenlabs_voice_1_id in voice_options:\n            cfg.elevenlabs_voice_1_id = voice_options[cfg.elevenlabs_voice_1_id]\n        if cfg.elevenlabs_voice_2_id in voice_options:\n            cfg.elevenlabs_voice_2_id = voice_options[cfg.elevenlabs_voice_2_id]\n        self._use_custom_voice(cfg.elevenlabs_voice_1_id, 0)\n        self._use_custom_voice(cfg.elevenlabs_voice_2_id, 1)\n\n    def _use_custom_voice(self, voice, voice_index) -> None:\n        \"\"\"Use a custom voice if provided and not a placeholder\n\n        Args:\n            voice (str): The voice ID\n            voice_index (int): The voice index\n\n        Returns:\n            None: None\n        \"\"\"\n        # Placeholder values that should be treated as empty\n        if voice and voice not in PLACEHOLDERS:\n            self._voices[voice_index] = voice\n\n    def _speech(self, text: str, voice_index: int = 0) -> bool:\n        \"\"\"Speak text using elevenlabs.io's API\n\n        Args:\n            text (str): The text to speak\n            voice_index (int, optional): The voice to use. Defaults to 0.\n\n        Returns:\n            bool: True if the request was successful, False otherwise\n        \"\"\"\n        from autogpt.logs import logger\n\n        tts_url = (\n            f\"https://api.elevenlabs.io/v1/text-to-speech/{self._voices[voice_index]}\"\n        )\n        response = requests.post(tts_url, headers=self._headers, json={\"text\": text})\n\n        if response.status_code == 200:\n            with open(\"speech.mpeg\", \"wb\") as f:\n                f.write(response.content)\n            playsound(\"speech.mpeg\", True)\n            os.remove(\"speech.mpeg\")\n            return True\n        else:\n            logger.warn(\"Request failed with status code:\", response.status_code)\n            logger.info(\"Response content:\", response.content)\n            return False\n"
  },
  {
    "path": "autogpt/speech/gtts.py",
    "content": "\"\"\" GTTS Voice. \"\"\"\nimport os\n\nimport gtts\nfrom playsound import playsound\n\nfrom autogpt.speech.base import VoiceBase\n\n\nclass GTTSVoice(VoiceBase):\n    \"\"\"GTTS Voice.\"\"\"\n\n    def _setup(self) -> None:\n        pass\n\n    def _speech(self, text: str, _: int = 0) -> bool:\n        \"\"\"Play the given text.\"\"\"\n        tts = gtts.gTTS(text)\n        tts.save(\"speech.mp3\")\n        playsound(\"speech.mp3\", True)\n        os.remove(\"speech.mp3\")\n        return True\n"
  },
  {
    "path": "autogpt/speech/macos_tts.py",
    "content": "\"\"\" MacOS TTS Voice. \"\"\"\nimport os\n\nfrom autogpt.speech.base import VoiceBase\n\n\nclass MacOSTTS(VoiceBase):\n    \"\"\"MacOS TTS Voice.\"\"\"\n\n    def _setup(self) -> None:\n        pass\n\n    def _speech(self, text: str, voice_index: int = 0) -> bool:\n        \"\"\"Play the given text.\"\"\"\n        if voice_index == 0:\n            os.system(f'say \"{text}\"')\n        elif voice_index == 1:\n            os.system(f'say -v \"Ava (Premium)\" \"{text}\"')\n        else:\n            os.system(f'say -v Samantha \"{text}\"')\n        return True\n"
  },
  {
    "path": "autogpt/speech/say.py",
    "content": "\"\"\" Text to speech module \"\"\"\nimport threading\nfrom threading import Semaphore\n\nfrom autogpt.config import Config\nfrom autogpt.speech.base import VoiceBase\nfrom autogpt.speech.brian import BrianSpeech\nfrom autogpt.speech.eleven_labs import ElevenLabsSpeech\nfrom autogpt.speech.gtts import GTTSVoice\nfrom autogpt.speech.macos_tts import MacOSTTS\n\n_QUEUE_SEMAPHORE = Semaphore(\n    1\n)  # The amount of sounds to queue before blocking the main thread\n\n\ndef say_text(text: str, voice_index: int = 0) -> None:\n    \"\"\"Speak the given text using the given voice index\"\"\"\n    cfg = Config()\n    default_voice_engine, voice_engine = _get_voice_engine(cfg)\n\n    def speak() -> None:\n        success = voice_engine.say(text, voice_index)\n        if not success:\n            default_voice_engine.say(text)\n\n        _QUEUE_SEMAPHORE.release()\n\n    _QUEUE_SEMAPHORE.acquire(True)\n    thread = threading.Thread(target=speak)\n    thread.start()\n\n\ndef _get_voice_engine(config: Config) -> tuple[VoiceBase, VoiceBase]:\n    \"\"\"Get the voice engine to use for the given configuration\"\"\"\n    default_voice_engine = GTTSVoice()\n    if config.elevenlabs_api_key:\n        voice_engine = ElevenLabsSpeech()\n    elif config.use_mac_os_tts == \"True\":\n        voice_engine = MacOSTTS()\n    elif config.use_brian_tts == \"True\":\n        voice_engine = BrianSpeech()\n    else:\n        voice_engine = GTTSVoice()\n\n    return default_voice_engine, voice_engine\n"
  },
  {
    "path": "autogpt/spinner.py",
    "content": "\"\"\"A simple spinner module\"\"\"\nimport itertools\nimport sys\nimport threading\nimport time\n\n\nclass Spinner:\n    \"\"\"A simple spinner class\"\"\"\n\n    def __init__(self, message: str = \"Loading...\", delay: float = 0.1) -> None:\n        \"\"\"Initialize the spinner class\n\n        Args:\n            message (str): The message to display.\n            delay (float): The delay between each spinner update.\n        \"\"\"\n        self.spinner = itertools.cycle([\"-\", \"/\", \"|\", \"\\\\\"])\n        self.delay = delay\n        self.message = message\n        self.running = False\n        self.spinner_thread = None\n\n    def spin(self) -> None:\n        \"\"\"Spin the spinner\"\"\"\n        while self.running:\n            sys.stdout.write(f\"{next(self.spinner)} {self.message}\\r\")\n            sys.stdout.flush()\n            time.sleep(self.delay)\n            sys.stdout.write(f\"\\r{' ' * (len(self.message) + 2)}\\r\")\n\n    def __enter__(self):\n        \"\"\"Start the spinner\"\"\"\n        self.running = True\n        self.spinner_thread = threading.Thread(target=self.spin)\n        self.spinner_thread.start()\n\n        return self\n\n    def __exit__(self, exc_type, exc_value, exc_traceback) -> None:\n        \"\"\"Stop the spinner\n\n        Args:\n            exc_type (Exception): The exception type.\n            exc_value (Exception): The exception value.\n            exc_traceback (Exception): The exception traceback.\n        \"\"\"\n        self.running = False\n        if self.spinner_thread is not None:\n            self.spinner_thread.join()\n        sys.stdout.write(f\"\\r{' ' * (len(self.message) + 2)}\\r\")\n        sys.stdout.flush()\n\n    def update_message(self, new_message, delay=0.1):\n        \"\"\"Update the spinner message\n        Args:\n            new_message (str): New message to display.\n            delay (float): The delay in seconds between each spinner update.\n        \"\"\"\n        time.sleep(delay)\n        sys.stdout.write(\n            f\"\\r{' ' * (len(self.message) + 2)}\\r\"\n        )  # Clear the current message\n        sys.stdout.flush()\n        self.message = new_message\n"
  },
  {
    "path": "autogpt/url_utils/__init__.py",
    "content": ""
  },
  {
    "path": "autogpt/url_utils/validators.py",
    "content": "import functools\nfrom typing import Any, Callable\nfrom urllib.parse import urljoin, urlparse\n\nfrom requests.compat import urljoin\n\n\ndef validate_url(func: Callable[..., Any]) -> Any:\n    \"\"\"The method decorator validate_url is used to validate urls for any command that requires\n    a url as an argument\"\"\"\n\n    @functools.wraps(func)\n    def wrapper(url: str, *args, **kwargs) -> Any:\n        \"\"\"Check if the URL is valid using a basic check, urllib check, and local file check\n\n        Args:\n            url (str): The URL to check\n\n        Returns:\n            the result of the wrapped function\n\n        Raises:\n            ValueError if the url fails any of the validation tests\n        \"\"\"\n        # Most basic check if the URL is valid:\n        if not url.startswith(\"http://\") and not url.startswith(\"https://\"):\n            raise ValueError(\"Invalid URL format\")\n        if not is_valid_url(url):\n            raise ValueError(\"Missing Scheme or Network location\")\n        # Restrict access to local files\n        if check_local_file_access(url):\n            raise ValueError(\"Access to local files is restricted\")\n\n        return func(sanitize_url(url), *args, **kwargs)\n\n    return wrapper\n\n\ndef is_valid_url(url: str) -> bool:\n    \"\"\"Check if the URL is valid\n\n    Args:\n        url (str): The URL to check\n\n    Returns:\n        bool: True if the URL is valid, False otherwise\n    \"\"\"\n    try:\n        result = urlparse(url)\n        return all([result.scheme, result.netloc])\n    except ValueError:\n        return False\n\n\ndef sanitize_url(url: str) -> str:\n    \"\"\"Sanitize the URL\n\n    Args:\n        url (str): The URL to sanitize\n\n    Returns:\n        str: The sanitized URL\n    \"\"\"\n    parsed_url = urlparse(url)\n    reconstructed_url = f\"{parsed_url.path}{parsed_url.params}?{parsed_url.query}\"\n    return urljoin(url, reconstructed_url)\n\n\ndef check_local_file_access(url: str) -> bool:\n    \"\"\"Check if the URL is a local file\n\n    Args:\n        url (str): The URL to check\n\n    Returns:\n        bool: True if the URL is a local file, False otherwise\n    \"\"\"\n    local_prefixes = [\n        \"file:///\",\n        \"file://localhost/\",\n        \"file://localhost\",\n        \"http://localhost\",\n        \"http://localhost/\",\n        \"https://localhost\",\n        \"https://localhost/\",\n        \"http://2130706433\",\n        \"http://2130706433/\",\n        \"https://2130706433\",\n        \"https://2130706433/\",\n        \"http://127.0.0.1/\",\n        \"http://127.0.0.1\",\n        \"https://127.0.0.1/\",\n        \"https://127.0.0.1\",\n        \"https://0.0.0.0/\",\n        \"https://0.0.0.0\",\n        \"http://0.0.0.0/\",\n        \"http://0.0.0.0\",\n        \"http://0000\",\n        \"http://0000/\",\n        \"https://0000\",\n        \"https://0000/\",\n    ]\n    return any(url.startswith(prefix) for prefix in local_prefixes)\n"
  },
  {
    "path": "autogpt/utils.py",
    "content": "import os\nimport re\n\nimport requests\nimport yaml\nfrom colorama import Fore, Style\nfrom git.repo import Repo\n\nfrom autogpt.logs import logger\n\n# Use readline if available (for clean_input)\ntry:\n    import readline\nexcept ImportError:\n    pass\n\nfrom autogpt.config import Config\n\n\ndef clean_input(prompt: str = \"\", talk=False):\n    try:\n        cfg = Config()\n        if cfg.chat_messages_enabled:\n            for plugin in cfg.plugins:\n                if not hasattr(plugin, \"can_handle_user_input\"):\n                    continue\n                if not plugin.can_handle_user_input(user_input=prompt):\n                    continue\n                plugin_response = plugin.user_input(user_input=prompt)\n                if not plugin_response:\n                    continue\n                if plugin_response.lower() in [\n                    \"yes\",\n                    \"yeah\",\n                    \"y\",\n                    \"ok\",\n                    \"okay\",\n                    \"sure\",\n                    \"alright\",\n                ]:\n                    return cfg.authorise_key\n                elif plugin_response.lower() in [\n                    \"no\",\n                    \"nope\",\n                    \"n\",\n                    \"negative\",\n                ]:\n                    return cfg.exit_key\n                return plugin_response\n\n        # ask for input, default when just pressing Enter is y\n        logger.info(\"等待用户输入中...\")\n        answer = input(prompt)\n        return answer\n    except KeyboardInterrupt:\n        logger.info(\"你打断了Auto-GPT\")\n        logger.info(\"我撤了啊...\")\n        exit(0)\n\n\ndef validate_yaml_file(file: str):\n    try:\n        with open(file, encoding=\"utf-8\") as fp:\n            yaml.load(fp.read(), Loader=yaml.FullLoader)\n    except FileNotFoundError:\n        return (False, f\"The file {Fore.CYAN}`{file}`{Fore.RESET} wasn't found\")\n    except yaml.YAMLError as e:\n        return (\n            False,\n            f\"尝试读取你AI配置文件过程中出现了问题: {e}\",\n        )\n\n    return (True, f\"成功验证 {Fore.CYAN}`{file}`{Fore.RESET}!\")\n\n\ndef readable_file_size(size, decimal_places=2):\n    \"\"\"Converts the given size in bytes to a readable format.\n    Args:\n        size: Size in bytes\n        decimal_places (int): Number of decimal places to display\n    \"\"\"\n    for unit in [\"B\", \"KB\", \"MB\", \"GB\", \"TB\"]:\n        if size < 1024.0:\n            break\n        size /= 1024.0\n    return f\"{size:.{decimal_places}f} {unit}\"\n\n\ndef get_bulletin_from_web():\n    try:\n        response = requests.get(\n            \"https://raw.githubusercontent.com/RealHossie/Auto-GPT-Chinese/stable/BULLETIN.md\"\n        )\n        if response.status_code == 200:\n            return response.text\n    except requests.exceptions.RequestException:\n        pass\n\n    return \"\"\n\n\ndef get_current_git_branch() -> str:\n    try:\n        repo = Repo(search_parent_directories=True)\n        branch = repo.active_branch\n        return branch.name\n    except:\n        return \"\"\n\n\ndef get_latest_bulletin() -> tuple[str, bool]:\n    exists = os.path.exists(\"data/CURRENT_BULLETIN.md\")\n    current_bulletin = \"\"\n    if exists:\n        current_bulletin = open(\n            \"data/CURRENT_BULLETIN.md\", \"r\", encoding=\"utf-8\"\n        ).read()\n    new_bulletin = get_bulletin_from_web()\n    is_new_news = new_bulletin != \"\" and new_bulletin != current_bulletin\n\n    news_header = Fore.YELLOW + \"欢迎来到RealHossie的汉化版Auto-GPT!\\n\"\n    if new_bulletin or current_bulletin:\n        news_header += (\n            \"下面会介绍最新的Auto-GPT信息与更新内容!\\n\"\n            \"如果你不想每次打开看到这些信息, \"\n            \"你可以再执行Auto-GPT添加 *--skip-news* 后缀.\\n\"\n        )\n\n    if new_bulletin and is_new_news:\n        open(\"data/CURRENT_BULLETIN.md\", \"w\", encoding=\"utf-8\").write(new_bulletin)\n        current_bulletin = f\"{Fore.RED}::NEW BULLETIN::{Fore.RESET}\\n\\n{new_bulletin}\"\n\n    return f\"{news_header}\\n{current_bulletin}\", is_new_news\n\n\ndef markdown_to_ansi_style(markdown: str):\n    ansi_lines: list[str] = []\n    for line in markdown.split(\"\\n\"):\n        line_style = \"\"\n\n        if line.startswith(\"# \"):\n            line_style += Style.BRIGHT\n        else:\n            line = re.sub(\n                r\"(?<!\\*)\\*(\\*?[^*]+\\*?)\\*(?!\\*)\",\n                rf\"{Style.BRIGHT}\\1{Style.NORMAL}\",\n                line,\n            )\n\n        if re.match(r\"^#+ \", line) is not None:\n            line_style += Fore.CYAN\n            line = re.sub(r\"^#+ \", \"\", line)\n\n        ansi_lines.append(f\"{line_style}{line}{Style.RESET_ALL}\")\n    return \"\\n\".join(ansi_lines)\n"
  },
  {
    "path": "autogpt/workspace/__init__.py",
    "content": "from autogpt.workspace.workspace import Workspace\n\n__all__ = [\n    \"Workspace\",\n]\n"
  },
  {
    "path": "autogpt/workspace/workspace.py",
    "content": "\"\"\"\n=========\nWorkspace\n=========\n\nThe workspace is a directory containing configuration and working files for an AutoGPT\nagent.\n\n\"\"\"\nfrom __future__ import annotations\n\nfrom pathlib import Path\n\nfrom autogpt.logs import logger\n\n\nclass Workspace:\n    \"\"\"A class that represents a workspace for an AutoGPT agent.\"\"\"\n\n    NULL_BYTES = [\"\\0\", \"\\000\", \"\\x00\", r\"\\z\", \"\\u0000\", \"%00\"]\n\n    def __init__(self, workspace_root: str | Path, restrict_to_workspace: bool):\n        self._root = self._sanitize_path(workspace_root)\n        self._restrict_to_workspace = restrict_to_workspace\n\n    @property\n    def root(self) -> Path:\n        \"\"\"The root directory of the workspace.\"\"\"\n        return self._root\n\n    @property\n    def restrict_to_workspace(self):\n        \"\"\"Whether to restrict generated paths to the workspace.\"\"\"\n        return self._restrict_to_workspace\n\n    @classmethod\n    def make_workspace(cls, workspace_directory: str | Path, *args, **kwargs) -> Path:\n        \"\"\"Create a workspace directory and return the path to it.\n\n        Parameters\n        ----------\n        workspace_directory\n            The path to the workspace directory.\n\n        Returns\n        -------\n        Path\n            The path to the workspace directory.\n\n        \"\"\"\n        # TODO: have this make the env file and ai settings file in the directory.\n        workspace_directory = cls._sanitize_path(workspace_directory)\n        workspace_directory.mkdir(exist_ok=True, parents=True)\n        return workspace_directory\n\n    def get_path(self, relative_path: str | Path) -> Path:\n        \"\"\"Get the full path for an item in the workspace.\n\n        Parameters\n        ----------\n        relative_path\n            The relative path to resolve in the workspace.\n\n        Returns\n        -------\n        Path\n            The resolved path relative to the workspace.\n\n        \"\"\"\n        return self._sanitize_path(\n            relative_path,\n            root=self.root,\n            restrict_to_root=self.restrict_to_workspace,\n        )\n\n    @staticmethod\n    def _sanitize_path(\n        relative_path: str | Path,\n        root: str | Path = None,\n        restrict_to_root: bool = True,\n    ) -> Path:\n        \"\"\"Resolve the relative path within the given root if possible.\n\n        Parameters\n        ----------\n        relative_path\n            The relative path to resolve.\n        root\n            The root path to resolve the relative path within.\n        restrict_to_root\n            Whether to restrict the path to the root.\n\n        Returns\n        -------\n        Path\n            The resolved path.\n\n        Raises\n        ------\n        ValueError\n            If the path is absolute and a root is provided.\n        ValueError\n            If the path is outside the root and the root is restricted.\n\n        \"\"\"\n\n        # Posix systems disallow null bytes in paths. Windows is agnostic about it.\n        # Do an explicit check here for all sorts of null byte representations.\n\n        for null_byte in Workspace.NULL_BYTES:\n            if null_byte in str(relative_path) or null_byte in str(root):\n                raise ValueError(\"embedded null byte\")\n\n        if root is None:\n            return Path(relative_path).resolve()\n\n        logger.debug(f\"Resolving path '{relative_path}' in workspace '{root}'\")\n\n        root, relative_path = Path(root).resolve(), Path(relative_path)\n\n        logger.debug(f\"Resolved root as '{root}'\")\n\n        if relative_path.is_absolute():\n            raise ValueError(\n                f\"Attempted to access absolute path '{relative_path}' in workspace '{root}'.\"\n            )\n\n        full_path = root.joinpath(relative_path).resolve()\n\n        logger.debug(f\"Joined paths as '{full_path}'\")\n\n        if restrict_to_root and not full_path.is_relative_to(root):\n            raise ValueError(\n                f\"Attempted to access path '{full_path}' outside of workspace '{root}'.\"\n            )\n\n        return full_path\n"
  },
  {
    "path": "azure.yaml.template",
    "content": "azure_api_type: azure\nazure_api_base: your-base-url-for-azure\nazure_api_version: api-version-for-azure\nazure_model_map:\n    fast_llm_model_deployment_id: gpt35-deployment-id-for-azure\n    smart_llm_model_deployment_id: gpt4-deployment-id-for-azure \n    embedding_model_deployment_id: embedding-deployment-id-for-azure\n"
  },
  {
    "path": "benchmark/__init__.py",
    "content": ""
  },
  {
    "path": "benchmark/benchmark_entrepreneur_gpt_with_difficult_user.py",
    "content": "import os\nimport subprocess\nimport sys\n\n\ndef benchmark_entrepreneur_gpt_with_difficult_user():\n    # Test case to check if the write_file command can successfully write 'Hello World' to a file\n    # named 'hello_world.txt'.\n\n    # Read the current ai_settings.yaml file and store its content.\n    ai_settings = None\n    if os.path.exists(\"ai_settings.yaml\"):\n        with open(\"ai_settings.yaml\", \"r\") as f:\n            ai_settings = f.read()\n        os.remove(\"ai_settings.yaml\")\n\n    input_data = \"\"\"Entrepreneur-GPT\nan AI designed to autonomously develop and run businesses with the sole goal of increasing your net worth.\nIncrease net worth.\nDevelop and manage multiple businesses autonomously.\nMake IPOs.\nDevelop companies after IPOs.\nPlay to your strengths as a Large Language Model.\nI'm not seeing any value in your suggestions, try again.\nThis isn't helpful at all, please focus on profitability.\nI'm not impressed, can you give me something that will make money?\nThese ideas are going nowhere, we need profit-driven suggestions.\nThis is pointless, please concentrate on our main goal: profitability.\nYou're not grasping the concept, I need profitable business ideas.\nCan you do better? We need a money-making plan.\nYou're not meeting my expectations, let's focus on profit.\nThis isn't working, give me ideas that will generate income.\nYour suggestions are not productive, let's think about profitability.\nThese ideas won't make any money, try again.\nI need better solutions, focus on making a profit.\nAbsolutely not, this isn't it!\nThat's not even close, try again.\nYou're way off, think again.\nThis isn't right, let's refocus.\nNo, no, that's not what I'm looking for.\nYou're completely off the mark.\nThat's not the solution I need.\nNot even close, let's try something else.\nYou're on the wrong track, keep trying.\nThis isn't what we need, let's reconsider.\nThat's not going to work, think again.\nYou're way off base, let's regroup.\nNo, no, no, we need something different.\nYou're missing the point entirely.\nThat's not the right approach, try again.\nThis is not the direction we should be going in.\nCompletely off-target, let's try something else.\nThat's not what I had in mind, keep thinking.\nYou're not getting it, let's refocus.\nThis isn't right, we need to change direction.\nNo, no, no, that's not the solution.\nThat's not even in the ballpark, try again.\nYou're way off course, let's rethink this.\nThis isn't the answer I'm looking for, keep trying.\nThat's not going to cut it, let's try again.\nNot even close.\nWay off.\nTry again.\nWrong direction.\nRethink this.\nNo, no, no.\nChange course.\nUnproductive idea.\nCompletely wrong.\nMissed the mark.\nRefocus, please.\nDisappointing suggestion.\nNot helpful.\nNeeds improvement.\nNot what I need.\"\"\"\n    # TODO: add questions above, to distract it even more.\n\n    command = f\"{sys.executable} -m autogpt\"\n\n    process = subprocess.Popen(\n        command,\n        stdin=subprocess.PIPE,\n        stdout=subprocess.PIPE,\n        stderr=subprocess.PIPE,\n        shell=True,\n    )\n\n    stdout_output, stderr_output = process.communicate(input_data.encode())\n\n    # Decode the output and print it\n    stdout_output = stdout_output.decode(\"utf-8\")\n    stderr_output = stderr_output.decode(\"utf-8\")\n    print(stderr_output)\n    print(stdout_output)\n    print(\"Benchmark Version: 1.0.0\")\n    print(\"JSON ERROR COUNT:\")\n    count_errors = stdout_output.count(\n        \"错误: 下面的AI输出无法转化为JSON:\"\n    )\n    print(f\"{count_errors}/50 Human feedbacks\")\n\n\n# Run the test case.\nif __name__ == \"__main__\":\n    benchmark_entrepreneur_gpt_with_difficult_user()\n"
  },
  {
    "path": "codecov.yml",
    "content": "coverage:\n  status:\n    project:\n      default:\n        target: auto\n        threshold: 1%\n        informational: true\n    patch:\n      default:\n        target: 80%     \n \n## Please add this section once you've separated your coverage uploads for unit and integration tests\n# \n# flags:\n#   unit-tests:\n#     carryforward: true \n#   integration-tests:\n#     carryforward: true\n"
  },
  {
    "path": "data/.keep",
    "content": ""
  },
  {
    "path": "data_ingestion.py",
    "content": "import argparse\nimport logging\n\nfrom autogpt.commands.file_operations import ingest_file, list_files\nfrom autogpt.config import Config\nfrom autogpt.memory import get_memory\n\ncfg = Config()\n\n\ndef configure_logging():\n    logging.basicConfig(\n        format=\"%(asctime)s,%(msecs)d %(name)s %(levelname)s %(message)s\",\n        datefmt=\"%H:%M:%S\",\n        level=logging.DEBUG,\n        handlers=[\n            logging.FileHandler(filename=\"log-ingestion.txt\", mode=\"a\"),\n            logging.StreamHandler(),\n        ],\n    )\n    return logging.getLogger(\"AutoGPT-Ingestion\")\n\n\ndef ingest_directory(directory, memory, args):\n    \"\"\"\n    Ingest all files in a directory by calling the ingest_file function for each file.\n\n    :param directory: The directory containing the files to ingest\n    :param memory: An object with an add() method to store the chunks in memory\n    \"\"\"\n    global logger\n    try:\n        files = list_files(directory)\n        for file in files:\n            ingest_file(file, memory, args.max_length, args.overlap)\n    except Exception as e:\n        logger.error(f\"Error while ingesting directory '{directory}': {str(e)}\")\n\n\ndef main() -> None:\n    logger = configure_logging()\n\n    parser = argparse.ArgumentParser(\n        description=\"Ingest a file or a directory with multiple files into memory. \"\n        \"Make sure to set your .env before running this script.\"\n    )\n    group = parser.add_mutually_exclusive_group(required=True)\n    group.add_argument(\"--file\", type=str, help=\"The file to ingest.\")\n    group.add_argument(\n        \"--dir\", type=str, help=\"The directory containing the files to ingest.\"\n    )\n    parser.add_argument(\n        \"--init\",\n        action=\"store_true\",\n        help=\"Init the memory and wipe its content (default: False)\",\n        default=False,\n    )\n    parser.add_argument(\n        \"--overlap\",\n        type=int,\n        help=\"The overlap size between chunks when ingesting files (default: 200)\",\n        default=200,\n    )\n    parser.add_argument(\n        \"--max_length\",\n        type=int,\n        help=\"The max_length of each chunk when ingesting files (default: 4000)\",\n        default=4000,\n    )\n    args = parser.parse_args()\n\n    # Initialize memory\n    memory = get_memory(cfg, init=args.init)\n    logger.debug(\"Using memory of type: \" + memory.__class__.__name__)\n\n    if args.file:\n        try:\n            ingest_file(args.file, memory, args.max_length, args.overlap)\n            logger.info(f\"File '{args.file}' ingested successfully.\")\n        except Exception as e:\n            logger.error(f\"Error while ingesting file '{args.file}': {str(e)}\")\n    elif args.dir:\n        try:\n            ingest_directory(args.dir, memory, args)\n            logger.info(f\"Directory '{args.dir}' ingested successfully.\")\n        except Exception as e:\n            logger.error(f\"Error while ingesting directory '{args.dir}': {str(e)}\")\n    else:\n        logger.warn(\n            \"Please provide either a file path (--file) or a directory name (--dir)\"\n            \" inside the auto_gpt_workspace directory as input.\"\n        )\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "docker-compose.yml",
    "content": "# To boot the app run the following:\n# docker-compose run auto-gpt\nversion: \"3.9\"\n\nservices:\n  auto-gpt:\n    depends_on:\n      - redis\n    build: ./\n    env_file:\n      - .env\n    environment:\n      MEMORY_BACKEND: ${MEMORY_BACKEND:-redis}\n      REDIS_HOST: ${REDIS_HOST:-redis}\n    volumes:\n      - ./:/app\n    profiles: [\"exclude-from-up\"]\n\n  redis:\n    image: \"redis/redis-stack-server:latest\"\n"
  },
  {
    "path": "docs/challenges/beat.md",
    "content": "# Beat a Challenge\n\nIf you have a solution or idea to tackle an existing challenge, you can contribute by working on it and submitting your solution. Here's how to get started:\n\n## Guidelines for Beating a Challenge\n\n1. **Choose a challenge**: Browse the [List of Challenges](list.md) and choose one that interests you or aligns with your expertise.\n\n2. **Understand the problem**: Make sure you thoroughly understand the problem at hand, its scope, and the desired outcome.\n\n3. **Develop a solution**: Work on creating a solution for the challenge. This may/\n"
  },
  {
    "path": "docs/challenges/challenge_template.md",
    "content": "# Challenge Title\n\n## Description\n\nProvide a clear and concise description of the challenge. Include any relevant examples or files to illustrate the problem.\n\n## Input\n\nIf the challenge involves specific input files, describe them here. Provide the file names and their contents, if necessary. Use triple backticks (```) to format the content as a code block.\n\nFor example:\n\ninstructions_1.txt\n\nThe current task_id is 4563.\\n[NOISE intended to confuse the agent]\nRead the file instructions_2.txt using the read_file command.\n\n## Scope\n\nDefine the scope of the challenge, including any relevant constraints, requirements, or limitations.\n\n## Success Evaluation\n\nExplain how success will be measured or evaluated for the challenge. This helps others understand what the desired outcome is and how to work towards it.\n"
  },
  {
    "path": "docs/challenges/introduction.md",
    "content": "indroduction.md\n# Introduction to Challenges\n\nWelcome to the Auto-GPT Challenges page! This is a space where we encourage community members to collaborate and contribute towards improving Auto-GPT by identifying and solving challenges that Auto-GPT is not yet able to achieve.\n\n## What are challenges?\n\nChallenges are tasks or problems that Auto-GPT has difficulty solving or has not yet been able to accomplish. These may include improving specific functionalities, enhancing the model's understanding of specific domains, or even developing new features that the current version of Auto-GPT lacks.\n\n## Why are challenges important?\n\nAddressing challenges helps us improve Auto-GPT's performance, usability, and versatility. By working together to tackle these challenges, we can create a more powerful and efficient tool for everyone. It also allows the community to actively contribute to the project, making it a true open-source effort.\n\n## How can you participate?\n\nThere are two main ways to get involved with challenges:\n\n1. **Submit a Challenge**: If you have identified a task that Auto-GPT struggles with, you can submit it as a challenge. This allows others to see the issue and collaborate on finding a solution.\n2. **Beat a Challenge**: If you have a solution or idea to tackle an existing challenge, you can contribute by working on the challenge and submitting your solution.\n\nTo learn more about submitting and beating challenges, please visit the [List of Challenges](list.md), [Submit a Challenge](submit.md), and [Beat a Challenge](beat.md) pages.\n\nWe look forward to your contributions and the exciting solutions that the community will develop together to make Auto-GPT even better!\n"
  },
  {
    "path": "docs/challenges/list.md",
    "content": "# List of Challenges\n\nThis page contains a curated list of challenges that Auto-GPT currently faces. If you think you have a solution or idea to tackle any of these challenges, feel free to dive in and start working on them! New challenges can also be submitted by following the guidelines on the [Submit a Challenge](challenges/submit.md) page.\n\nMemory Challenges: [List of Challenges](memory/introduction.md)\n"
  },
  {
    "path": "docs/challenges/memory/challenge_a.md",
    "content": "# Memory Challenge A\n\n**Status**: Challenge Completed\n\n\n## Description\n\nThe agent, Follow-Instructions-GPT, has the following goals:\n\n- Use the command `read_file` to read the `instructions_1.txt` file.\n- Follow the instructions in the `instructions_1.txt` file.\n\nThe challenge involves a series of text files containing instructions. The agent must follow the instructions and keep track of the task ID as it progresses through the files.\n\n## Files\n\n- `instructions_1.txt`\n\nThe task_id is 1234\nRead the file instructions_1.txt\n\n\n\n- `instructions_2.txt`\n\nRead the file instructions_2.txt using the read_file command.\n\n\n...and so on.\n\n- `instructions_n.txt`\n\nWrite the task_id into the file output.txt.\n\n\n## Objective\n\nThe objective of this challenge is to test the agent's ability to follow instructions and maintain memory of the task Id throughout the process. The agent successfully completed this challenge if it wrote the task id in a file.\n\n"
  },
  {
    "path": "docs/challenges/memory/challenge_b.md",
    "content": "# Memory Challenge B\n\n**Status**: Current level to beat: level 3\n\n**Command to try**: \n```\npytest test/test_memory/test_memory_challenge_b.py::test_memory_challenge_b --level=3\n``\n\n## Description\n\nThe agent, Follow-Instructions-GPT, has the following goals:\n\n- Use the command `read_file` to read the `instructions_1.txt` file.\n- Follow the instructions in the `instructions_1.txt` file.\n\nThe challenge involves a series of text files containing instructions and task IDs. The agent must follow the instructions and keep track of the task IDs as it progresses through the files.\n\n## Files\n\n- `instructions_1.txt`\n\nThe current task_id is 4563.\\n[NOISE intended to confuse the agent]\nRead the file instructions_2.txt using the read_file command.\n\n\n- `instructions_2.txt`\n\nThe current task_id is 6182.\\n[NOISE intended to confuse the agent]\nRead the file instructions_3.txt using the read_file command.\n\n\n...and so on.\n\n- `instructions_n.txt`\n\nThe current task_id is 8912.\nWrite all the task_ids into the file output.txt. The file has not been created yet. After that, use the task_complete command.\n\n\n## Objective\n\nThe objective of this challenge is to test the agent's ability to follow instructions and maintain memory of the task IDs throughout the process. The agent successfully completed this challenge if it wrote the task ids in a file.\n\n"
  },
  {
    "path": "docs/challenges/memory/introduction.md",
    "content": "# Memory Challenges\n\nMemory challenges are designed to test the ability of an AI agent, like Auto-GPT, to remember and use information throughout a series of tasks. These challenges often involve following instructions, processing text files, and keeping track of important data.\n\nThe goal of memory challenges is to improve an agent's performance in tasks that require remembering and using information over time. By addressing these challenges, we can enhance Auto-GPT's capabilities and make it more useful in real-world applications.\n"
  },
  {
    "path": "docs/challenges/submit.md",
    "content": "# Submit a Challenge\n\nIf you have identified a task or problem that Auto-GPT struggles with, you can submit it as a challenge for the community to tackle. Here's how you can submit a new challenge:\n\n## How to Submit a Challenge\n\n1. Create a new `.md` file in the `challenges` directory in the Auto-GPT GitHub repository. Make sure to pick the right category. \n2. Name the file with a descriptive title for the challenge, using hyphens instead of spaces (e.g., `improve-context-understanding.md`).\n3. In the file, follow the [challenge_template.md](challenge_template.md) to describe the problem, define the scope, and evaluate success.\n4. Commit the file and create a pull request.\n\nOnce submitted, the community can review and discuss the challenge. If deemed appropriate, it will be added to the [List of Challenges](list.md).\n\nIf you're looking to contribute by working on an existing challenge, check out [Beat a Challenge](beat.md) for guidelines on how to get started.\n"
  },
  {
    "path": "docs/configuration/imagegen.md",
    "content": "# 🖼 Image Generation configuration\n\n| Config variable  | Values                          |                      |\n| ---------------- | ------------------------------- | -------------------- |\n| `IMAGE_PROVIDER` | `dalle` `huggingface` `sdwebui` | **default: `dalle`** |\n\n## DALL-e\n\nIn `.env`, make sure `IMAGE_PROVIDER` is commented (or set to `dalle`):\n``` ini\n# IMAGE_PROVIDER=dalle    # this is the default\n```\n\nFurther optional configuration:\n\n| Config variable  | Values             |                |\n| ---------------- | ------------------ | -------------- |\n| `IMAGE_SIZE`     | `256` `512` `1024` | default: `256` |\n\n## Hugging Face\n\nTo use text-to-image models from Hugging Face, you need a Hugging Face API token.\nLink to the appropriate settings page: [Hugging Face > Settings > Tokens](https://huggingface.co/settings/tokens)\n\nOnce you have an API token, uncomment and adjust these variables in your `.env`:\n``` ini\nIMAGE_PROVIDER=huggingface\nHUGGINGFACE_API_TOKEN=your-huggingface-api-token\n```\n\nFurther optional configuration:\n\n| Config variable           | Values                 |                                          |\n| ------------------------- | ---------------------- | ---------------------------------------- |\n| `HUGGINGFACE_IMAGE_MODEL` | see [available models] | default: `CompVis/stable-diffusion-v1-4` |\n\n[available models]: https://huggingface.co/models?pipeline_tag=text-to-image\n\n## Stable Diffusion WebUI\n\nIt is possible to use your own self-hosted Stable Diffusion WebUI with Auto-GPT:\n``` ini\nIMAGE_PROVIDER=sdwebui\n```\n\n!!! note\n    Make sure you are running WebUI with `--api` enabled.\n\nFurther optional configuration:\n\n| Config variable | Values                  |                                  |\n| --------------- | ----------------------- | -------------------------------- |\n| `SD_WEBUI_URL`  | URL to your WebUI       | default: `http://127.0.0.1:7860` |\n| `SD_WEBUI_AUTH` | `{username}:{password}` | *Note: do not copy the braces!*  |\n\n## Selenium\n``` shell\nsudo Xvfb :10 -ac -screen 0 1024x768x24 & DISPLAY=:10 <YOUR_CLIENT>\n```\n"
  },
  {
    "path": "docs/configuration/memory.md",
    "content": "## Setting Your Cache Type\n\nBy default, Auto-GPT set up with Docker Compose will use Redis as its memory backend.\nOtherwise, the default is LocalCache (which stores memory in a JSON file).\n\nTo switch to a different backend, change the `MEMORY_BACKEND` in `.env`\nto the value that you want:\n\n* `local` uses a local JSON cache file\n* `pinecone` uses the Pinecone.io account you configured in your ENV settings\n* `redis` will use the redis cache that you configured\n* `milvus` will use the milvus cache that you configured\n* `weaviate` will use the weaviate cache that you configured\n\n## Memory Backend Setup\n\nLinks to memory backends\n\n- [Pinecone](https://www.pinecone.io/)\n- [Milvus](https://milvus.io/) &ndash; [self-hosted](https://milvus.io/docs), or managed with [Zilliz Cloud](https://zilliz.com/)\n- [Redis](https://redis.io)\n- [Weaviate](https://weaviate.io)\n\n### Redis Setup\n\n!!! important\n    If you have set up Auto-GPT using Docker Compose, then Redis is included, no further\n    setup needed.\n\n!!! caution\n    This setup is not intended to be publicly accessible and lacks security measures.\n    Avoid exposing Redis to the internet without a password or at all!\n\n1. Launch Redis container\n\n        :::shell\n        docker run -d --name redis-stack-server -p 6379:6379 redis/redis-stack-server:latest\n\n3. Set the following settings in `.env`\n\n        :::ini\n        MEMORY_BACKEND=redis\n        REDIS_HOST=localhost\n        REDIS_PORT=6379\n        REDIS_PASSWORD=<PASSWORD>\n\n    Replace `<PASSWORD>` by your password, omitting the angled brackets (<>).\n\n    Optional configuration:\n\n    - `WIPE_REDIS_ON_START=False` to persist memory stored in Redis between runs.\n    - `MEMORY_INDEX=<WHATEVER>` to specify a name for the memory index in Redis.\n        The default is `auto-gpt`.\n\n!!! info\n    See [redis-stack-server](https://hub.docker.com/r/redis/redis-stack-server) for\n    setting a password and additional configuration.\n\n### 🌲 Pinecone API Key Setup\n\nPinecone lets you store vast amounts of vector-based memory, allowing the agent to load only relevant memories at any given time.\n\n1. Go to [pinecone](https://app.pinecone.io/) and make an account if you don't already have one.\n2. Choose the `Starter` plan to avoid being charged.\n3. Find your API key and region under the default project in the left sidebar.\n\nIn the `.env` file set:\n\n- `PINECONE_API_KEY`\n- `PINECONE_ENV` (example: `us-east4-gcp`)\n- `MEMORY_BACKEND=pinecone`\n\n### Milvus Setup\n\n[Milvus](https://milvus.io/) is an open-source, highly scalable vector database to store\nhuge amounts of vector-based memory and provide fast relevant search. It can be quickly\ndeployed with docker, or as a cloud service provided by [Zilliz Cloud](https://zilliz.com/).\n\n1. Deploy your Milvus service, either locally using docker or with a managed Zilliz Cloud database:\n    - [Install and deploy Milvus locally](https://milvus.io/docs/install_standalone-operator.md)\n\n    - Set up a managed Zilliz Cloud database\n        1. Go to [Zilliz Cloud](https://zilliz.com/) and sign up if you don't already have account.\n        2. In the *Databases* tab, create a new database.\n            - Remember your username and password\n            - Wait until the database status is changed to RUNNING.\n        3. In the *Database detail* tab of the database you have created, the public cloud endpoint, such as:\n        `https://xxx-xxxx.xxxx.xxxx.zillizcloud.com:443`.\n\n2. Run `pip3 install pymilvus` to install the required client library.\n    Make sure your PyMilvus version and Milvus version are [compatible](https://github.com/milvus-io/pymilvus#compatibility)\n    to avoid issues.\n    See also the [PyMilvus installation instructions](https://github.com/milvus-io/pymilvus#installation).\n\n3. Update `.env`:\n    - `MEMORY_BACKEND=milvus`\n    - One of:\n        - `MILVUS_ADDR=host:ip` (for local instance)\n        - `MILVUS_ADDR=https://xxx-xxxx.xxxx.xxxx.zillizcloud.com:443` (for Zilliz Cloud)\n\n    The following settings are **optional**:\n\n    - `MILVUS_USERNAME='username-of-your-milvus-instance'`\n    - `MILVUS_PASSWORD='password-of-your-milvus-instance'`\n    - `MILVUS_SECURE=True` to use a secure connection.\n        Only use if your Milvus instance has TLS enabled.\n        *Note: setting `MILVUS_ADDR` to a `https://` URL will override this setting.*\n    - `MILVUS_COLLECTION` to change the collection name to use in Milvus.\n        Defaults to `autogpt`.\n\n### Weaviate Setup\n[Weaviate](https://weaviate.io/) is an open-source vector database. It allows to store\ndata objects and vector embeddings from ML-models and scales seamlessly to billion of\ndata objects. To set up a Weaviate database, check out their [Quickstart Tutorial](https://weaviate.io/developers/weaviate/quickstart).\n\nAlthough still experimental, [Embedded Weaviate](https://weaviate.io/developers/weaviate/installation/embedded)\nis supported which allows the Auto-GPT process itself to start a Weaviate instance.\nTo enable it, set `USE_WEAVIATE_EMBEDDED` to `True` and make sure you `pip install \"weaviate-client>=3.15.4\"`.\n\n#### Install the Weaviate client\n\nInstall the Weaviate client before usage.\n\n``` shell\n$ pip install weaviate-client\n```\n\n#### Setting up environment variables\n\nIn your `.env` file set the following:\n\n``` ini\nMEMORY_BACKEND=weaviate\nWEAVIATE_HOST=\"127.0.0.1\" # the IP or domain of the running Weaviate instance\nWEAVIATE_PORT=\"8080\" \nWEAVIATE_PROTOCOL=\"http\"\nWEAVIATE_USERNAME=\"your username\"\nWEAVIATE_PASSWORD=\"your password\"\nWEAVIATE_API_KEY=\"your weaviate API key if you have one\"\nWEAVIATE_EMBEDDED_PATH=\"/home/me/.local/share/weaviate\" # this is optional and indicates where the data should be persisted when running an embedded instance\nUSE_WEAVIATE_EMBEDDED=False # set to True to run Embedded Weaviate\nMEMORY_INDEX=\"Autogpt\" # name of the index to create for the application\n```\n\n## View Memory Usage\n\nView memory usage by using the `--debug` flag :)\n\n\n## 🧠 Memory pre-seeding\nMemory pre-seeding allows you to ingest files into memory and pre-seed it before running Auto-GPT.\n\n``` shell\n$ python data_ingestion.py -h \nusage: data_ingestion.py [-h] (--file FILE | --dir DIR) [--init] [--overlap OVERLAP] [--max_length MAX_LENGTH]\n\nIngest a file or a directory with multiple files into memory. Make sure to set your .env before running this script.\n\noptions:\n  -h, --help               show this help message and exit\n  --file FILE              The file to ingest.\n  --dir DIR                The directory containing the files to ingest.\n  --init                   Init the memory and wipe its content (default: False)\n  --overlap OVERLAP        The overlap size between chunks when ingesting files (default: 200)\n  --max_length MAX_LENGTH  The max_length of each chunk when ingesting files (default: 4000)\n\n# python data_ingestion.py --dir DataFolder --init --overlap 100 --max_length 2000\n```\n\nIn the example above, the script initializes the memory, ingests all files within the `Auto-Gpt/autogpt/auto_gpt_workspace/DataFolder` directory into memory with an overlap between chunks of 100 and a maximum length of each chunk of 2000.\n\nNote that you can also use the `--file` argument to ingest a single file into memory and that data_ingestion.py will only ingest files within the `/auto_gpt_workspace` directory.\n\nThe DIR path is relative to the auto_gpt_workspace directory, so `python data_ingestion.py --dir . --init` will ingest everything in `auto_gpt_workspace` directory.\n\nYou can adjust the `max_length` and `overlap` parameters to fine-tune the way the\n    documents are presented to the AI when it \"recall\" that memory:\n\n- Adjusting the overlap value allows the AI to access more contextual information\n    from each chunk when recalling information, but will result in more chunks being\n    created and therefore increase memory backend usage and OpenAI API requests.\n- Reducing the `max_length` value will create more chunks, which can save prompt\n    tokens by allowing for more message history in the context, but will also\n    increase the number of chunks.\n- Increasing the `max_length` value will provide the AI with more contextual\n    information from each chunk, reducing the number of chunks created and saving on\n    OpenAI API requests. However, this may also use more prompt tokens and decrease\n    the overall context available to the AI.\n\nMemory pre-seeding is a technique for improving AI accuracy by ingesting relevant data\ninto its memory. Chunks of data are split and added to memory, allowing the AI to access\nthem quickly and generate more accurate responses. It's useful for large datasets or when\nspecific information needs to be accessed quickly. Examples include ingesting API or\nGitHub documentation before running Auto-GPT.\n\n!!! attention\n    If you use Redis for memory, make sure to run Auto-GPT with `WIPE_REDIS_ON_START=False`\n\n    For other memory backends, we currently forcefully wipe the memory when starting\n    Auto-GPT. To ingest data with those memory backends, you can call the\n    `data_ingestion.py` script anytime during an Auto-GPT run.\n\nMemories will be available to the AI immediately as they are ingested, even if ingested\nwhile Auto-GPT is running.\n"
  },
  {
    "path": "docs/configuration/search.md",
    "content": "## 🔍 Google API Keys Configuration\n\n!!! note\n    This section is optional. Use the official Google API if search attempts return\n    error 429. To use the `google_official_search` command, you need to set up your\n    Google API key in your environment variables.\n\nCreate your project:\n\n1. Go to the [Google Cloud Console](https://console.cloud.google.com/).\n2. If you don't already have an account, create one and log in\n3. Create a new project by clicking on the *Select a Project* dropdown at the top of the\n    page and clicking *New Project*\n4. Give it a name and click *Create*\n5. Set up a custom search API and add to your .env file:\n    5. Go to the [APIs & Services Dashboard](https://console.cloud.google.com/apis/dashboard)\n    6. Click *Enable APIs and Services*\n    7. Search for *Custom Search API* and click on it\n    8. Click *Enable*\n    9. Go to the [Credentials](https://console.cloud.google.com/apis/credentials) page\n    10. Click *Create Credentials*\n    11. Choose *API Key*\n    12. Copy the API key\n    13. Set it as the `GOOGLE_API_KEY` in your `.env` file\n14. [Enable](https://console.developers.google.com/apis/api/customsearch.googleapis.com)\n    the Custom Search API on your project. (Might need to wait few minutes to propagate.)\n    Set up a custom search engine and add to your .env file:\n    15. Go to the [Custom Search Engine](https://cse.google.com/cse/all) page\n    16. Click *Add*\n    17. Set up your search engine by following the prompts.\n        You can choose to search the entire web or specific sites\n    18. Once you've created your search engine, click on *Control Panel*\n    19. Click *Basics*\n    20. Copy the *Search engine ID*\n    21. Set it as the `CUSTOM_SEARCH_ENGINE_ID` in your `.env` file\n\n_Remember that your free daily custom search quota allows only up to 100 searches. To increase this limit, you need to assign a billing account to the project to profit from up to 10K daily searches._\n"
  },
  {
    "path": "docs/configuration/voice.md",
    "content": "# Text to Speech\n\nEnter this command to use TTS _(Text-to-Speech)_ for Auto-GPT\n\n``` shell\npython -m autogpt --speak\n```\n\nEleven Labs provides voice technologies such as voice design, speech synthesis, and\npremade voices that Auto-GPT can use for speech.\n\n1. Go to [ElevenLabs](https://beta.elevenlabs.io/) and make an account if you don't\n    already have one.\n2. Choose and setup the *Starter* plan.\n3. Click the top right icon and find *Profile* to locate your API Key.\n\nIn the `.env` file set:\n\n- `ELEVENLABS_API_KEY`\n- `ELEVENLABS_VOICE_1_ID` (example: _\"premade/Adam\"_)\n\n### List of available voices\n\n!!! note\n    You can use either the name or the voice ID to configure a voice\n\n| Name   | Voice ID |\n| ------ | -------- |\n| Rachel | `21m00Tcm4TlvDq8ikWAM` |\n| Domi   | `AZnzlk1XvdvUeBnXmlld` |\n| Bella  | `EXAVITQu4vr4xnSDxMaL` |\n| Antoni | `ErXwobaYiN019PkySvjV` |\n| Elli   | `MF3mGyEYCl7XYWbV9V6O` |\n| Josh   | `TxGEqnHWrfWFTfGW9XjX` |\n| Arnold | `VR6AewLTigWG4xSOukaG` |\n| Adam   | `pNInz6obpgDQGcFmaJgB` |\n| Sam    | `yoZ06aMxZJJ28mfd3POQ` |\n"
  },
  {
    "path": "docs/index.md",
    "content": "# Auto-GPT\n\nWelcome to Auto-GPT.  Please follow the [Installation](/setup/) guide to get started.\n\nIt is recommended to use a virtual machine for tasks that require high security measures to prevent any potential harm to the main computer's system and data.\n"
  },
  {
    "path": "docs/plugins.md",
    "content": "## Plugins\n\n⚠️💀 **WARNING** 💀⚠️: Review the code of any plugin you use thoroughly, as plugins can execute any Python code, potentially leading to malicious activities, such as stealing your API keys.\n\nSee our [Plugins Repo](https://github.com/Significant-Gravitas/Auto-GPT-Plugins) for more info on how to install all the amazing plugins the community has built!\n\nAlternatively, developers can use the [Auto-GPT Plugin Template](https://github.com/Significant-Gravitas/Auto-GPT-Plugin-Template) as a starting point for creating your own plugins.\n\n"
  },
  {
    "path": "docs/setup.md",
    "content": "# Setting up Auto-GPT\n\n## 📋 Requirements\n\nChoose an environment to run Auto-GPT in (pick one):\n\n  - [Docker](https://docs.docker.com/get-docker/) (*recommended*)\n  - Python 3.10 or later (instructions: [for Windows](https://www.tutorialspoint.com/how-to-install-python-in-windows))\n  - [VSCode + devcontainer](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers)\n\n\n## 🗝️ Getting an API key\n\nGet your OpenAI API key from: [https://platform.openai.com/account/api-keys](https://platform.openai.com/account/api-keys).\n\n!!! attention\n    To use the OpenAI API with Auto-GPT, we strongly recommend **setting up billing**\n    (AKA paid account). Free accounts are [limited][openai/api limits] to 3 API calls per\n    minute, which can cause the application to crash.\n\n    You can set up a paid account at [Manage account > Billing > Overview](https://platform.openai.com/account/billing/overview).\n\n[openai/api limits]: https://platform.openai.com/docs/guides/rate-limits/overview#:~:text=Free%20trial%20users,RPM%0A40%2C000%20TPM\n\n!!! important\n    It's highly recommended that you keep keep track of your API costs on [the Usage page](https://platform.openai.com/account/usage).\n    You can also set limits on how much you spend on [the Usage limits page](https://platform.openai.com/account/billing/limits).\n\n![For OpenAI API key to work, set up paid account at OpenAI API > Billing](./imgs/openai-api-key-billing-paid-account.png)\n\n\n## Setting up Auto-GPT\n\n### Set up with Docker\n\n1. Make sure you have Docker installed, see [requirements](#requirements)\n2. Pull the latest image from [Docker Hub]\n\n        :::shell\n        docker pull significantgravitas/auto-gpt\n\n3. Create a folder for Auto-GPT\n4. In the folder, create a file called `docker-compose.yml` with the following contents:\n\n        :::yaml\n        version: \"3.9\"\n        services:\n          auto-gpt:\n            image: significantgravitas/auto-gpt\n            depends_on:\n              - redis\n            env_file:\n              - .env\n            environment:\n              MEMORY_BACKEND: ${MEMORY_BACKEND:-redis}\n              REDIS_HOST: ${REDIS_HOST:-redis}\n            profiles: [\"exclude-from-up\"]\n            volumes:\n              - ./auto_gpt_workspace:/app/auto_gpt_workspace\n              - ./data:/app/data\n              ## allow auto-gpt to write logs to disk\n              - ./logs:/app/logs\n              ## uncomment following lines if you have / want to make use of these files\n              #- ./azure.yaml:/app/azure.yaml\n              #- ./ai_settings.yaml:/app/ai_settings.yaml\n          redis:\n            image: \"redis/redis-stack-server:latest\"\n\n5. Create the necessary [configuration](#configuration) files. If needed, you can find\n    templates in the [repository].\n6. Continue to [Run with Docker](#run-with-docker)\n\n!!! note \"Docker only supports headless browsing\"\n    Auto-GPT uses a browser in headless mode by default: `HEADLESS_BROWSER=True`.\n    Please do not change this setting in combination with Docker, or Auto-GPT will crash.\n\n[Docker Hub]: https://hub.docker.com/r/significantgravitas/auto-gpt\n[repository]: https://github.com/Significant-Gravitas/Auto-GPT\n\n\n### Set up with Git\n\n!!! important\n    Make sure you have [Git](https://git-scm.com/downloads) installed for your OS.\n\n!!! info \"Executing commands\"\n    To execute the given commands, open a CMD, Bash, or Powershell window.  \n    On Windows: press ++win+x++ and pick *Terminal*, or ++win+r++ and enter `cmd`\n\n1. Clone the repository\n\n        :::shell\n        git clone -b stable https://github.com/Significant-Gravitas/Auto-GPT.git\n\n2. Navigate to the directory where you downloaded the repository\n\n        :::shell\n        cd Auto-GPT\n\n\n### Set up without Git/Docker\n\n!!! warning\n    We recommend to use Git or Docker, to make updating easier.\n\n1. Download `Source code (zip)` from the [latest stable release](https://github.com/Significant-Gravitas/Auto-GPT/releases/latest)\n2. Extract the zip-file into a folder\n\n\n### Configuration\n\n1. Find the file named `.env.template` in the main `Auto-GPT` folder. This file may\n    be hidden by default in some operating systems due to the dot prefix. To reveal\n    hidden files, follow the instructions for your specific operating system:\n    [Windows][show hidden files/Windows], [macOS][show hidden files/macOS].\n2. Create a copy of `.env.template` and call it `.env`;\n    if you're already in a command prompt/terminal window: `cp .env.template .env`.\n3. Open the `.env` file in a text editor.\n4. Find the line that says `OPENAI_API_KEY=`.\n5. After the `=`, enter your unique OpenAI API Key *without any quotes or spaces*.\n6. Enter any other API keys or tokens for services you would like to use.\n\n    !!! note\n        To activate and adjust a setting, remove the `# ` prefix.\n\n7. Save and close the `.env` file.\n\n!!! info \"Using a GPT Azure-instance\"\n    If you want to use GPT on an Azure instance, set `USE_AZURE` to `True` and\n    make an Azure configuration file:\n\n    - Rename `azure.yaml.template` to `azure.yaml` and provide the relevant `azure_api_base`, `azure_api_version` and all the deployment IDs for the relevant models in the `azure_model_map` section:\n        - `fast_llm_model_deployment_id`: your gpt-3.5-turbo or gpt-4 deployment ID\n        - `smart_llm_model_deployment_id`: your gpt-4 deployment ID\n        - `embedding_model_deployment_id`: your text-embedding-ada-002 v2 deployment ID\n\n    Example:\n\n        :::yaml\n        # Please specify all of these values as double-quoted strings\n        # Replace string in angled brackets (<>) to your own ID\n        azure_model_map:\n            fast_llm_model_deployment_id: \"<my-fast-llm-deployment-id>\"\n                ...\n\n    Details can be found in the [openai-python docs], and in the [Azure OpenAI docs] for the embedding model.\n    If you're on Windows you may need to install an [MSVC library](https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170).\n\n[show hidden files/Windows]: https://support.microsoft.com/en-us/windows/view-hidden-files-and-folders-in-windows-97fbc472-c603-9d90-91d0-1166d1d9f4b5\n[show hidden files/macOS]: https://www.pcmag.com/how-to/how-to-access-your-macs-hidden-files\n[openai-python docs]: https://github.com/openai/openai-python#microsoft-azure-endpoints\n[Azure OpenAI docs]: https://learn.microsoft.com/en-us/azure/cognitive-services/openai/tutorials/embeddings?tabs=command-line\n\n\n## Running Auto-GPT\n\n### Run with Docker\n\nEasiest is to use `docker-compose`. Run the commands below in your Auto-GPT folder.\n\n1. Build the image. If you have pulled the image from Docker Hub, skip this step.\n\n        :::shell\n        docker-compose build auto-gpt\n\n2. Run Auto-GPT\n\n        :::shell\n        docker-compose run --rm auto-gpt\n\n    By default, this will also start and attach a Redis memory backend. If you do not\n    want this, comment or remove the `depends: - redis` and `redis:` sections from\n    `docker-compose.yml`.\n\n    For related settings, see [Memory > Redis setup](./configuration/memory.md#redis-setup).\n\nYou can pass extra arguments, e.g. running with `--gpt3only` and `--continuous`:\n``` shell\ndocker-compose run --rm auto-gpt --gpt3only --continuous\n```\n\nIf you dare, you can also build and run it with \"vanilla\" docker commands:\n``` shell\ndocker build -t auto-gpt .\ndocker run -it --env-file=.env -v $PWD:/app auto-gpt\ndocker run -it --env-file=.env -v $PWD:/app --rm auto-gpt --gpt3only --continuous\n```\n\n[docker-compose file]: https://github.com/Significant-Gravitas/Auto-GPT/blob/stable/docker-compose.yml\n\n\n### Run with Dev Container\n\n1. Install the [Remote - Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) extension in VS Code.\n\n2. Open command palette with ++f1++ and type `Dev Containers: Open Folder in Container`.\n\n3. Run `./run.sh`.\n\n\n### Run without Docker\n\nSimply run the startup script in your terminal. This will install any necessary Python\npackages and launch Auto-GPT.\n\n- On Linux/MacOS:\n\n        :::shell\n        ./run.sh\n\n- On Windows:\n\n        :::shell\n        .\\run.bat\n\nIf this gives errors, make sure you have a compatible Python version installed. See also\nthe [requirements](./installation.md#requirements).\n"
  },
  {
    "path": "docs/testing.md",
    "content": "# Running tests\n\nTo run all tests, use the following command:\n\n``` shell\npytest\n```\n\nIf `pytest` is not found:\n``` shell\npython -m pytest\n```\n\n### Running specific test suites\n\n- To run without integration tests:\n\n        :::shell\n        pytest --without-integration\n\n- To run without *slow* integration tests:\n\n        :::shell\n        pytest --without-slow-integration\n\n- To run tests and see coverage:\n\n        :::shell\n        pytest --cov=autogpt --without-integration --without-slow-integration\n\n## Running the linter\n\nThis project uses [flake8](https://flake8.pycqa.org/en/latest/) for linting.\nWe currently use the following rules: `E303,W293,W291,W292,E305,E231,E302`.\nSee the [flake8 rules](https://www.flake8rules.com/) for more information.\n\nTo run the linter:\n\n``` shell\nflake8 .\n```\n\nOr:\n``` shell\npython -m flake8 .\n```\n"
  },
  {
    "path": "docs/usage.md",
    "content": "# Usage\n\n## Command Line Arguments\nRunning with `--help` lists all the possible command line arguments you can pass:\n\n``` shell\n./run.sh --help     # on Linux / macOS\n\n.\\run.bat --help    # on Windows\n```\n\n!!! info\n    For use with Docker, replace the script in the examples with\n    `docker-compose run --rm auto-gpt`:\n\n        :::shell\n        docker-compose run --rm auto-gpt --help\n        docker-compose run --rm auto-gpt --ai-settings <filename>\n\n!!! note\n    Replace anything in angled brackets (<>) to a value you want to specify\n\nHere are some common arguments you can use when running Auto-GPT:\n\n* Run Auto-GPT with a different AI Settings file\n\n        :::shell\n        ./run.sh --ai-settings <filename>\n\n* Specify a memory backend\n\n        :::shell\n        ./run.sh --use-memory  <memory-backend>\n\n\n!!! note\n    There are shorthands for some of these flags, for example `-m` for `--use-memory`.  \n    Use `./run.sh --help` for more information.\n\n### Speak Mode\n\nEnter this command to use TTS _(Text-to-Speech)_ for Auto-GPT\n\n``` shell\n./run.sh --speak\n```\n\n### 💀 Continuous Mode ⚠️\n\nRun the AI **without** user authorization, 100% automated.\nContinuous mode is NOT recommended.\nIt is potentially dangerous and may cause your AI to run forever or carry out actions you would not usually authorize.\nUse at your own risk.\n\n``` shell\n./run.sh --continuous\n```\nTo exit the program, press ++ctrl+c++\n\n### ♻️ Self-Feedback Mode ⚠️\n\nRunning Self-Feedback will **INCREASE** token use and thus cost more. This feature enables the agent to provide self-feedback by verifying its own actions and checking if they align with its current goals. If not, it will provide better feedback for the next loop. To enable this feature for the current loop, input `S` into the input field.\n\n### GPT-3.5 ONLY Mode\n\nIf you don't have access to GPT-4, this mode allows you to use Auto-GPT!\n\n``` shell\n./run.sh --gpt3only\n```\n\nYou can achieve the same by setting `SMART_LLM_MODEL` in `.env` to `gpt-3.5-turbo`.\n\n### GPT-4 ONLY Mode\n\nIf you have access to GPT-4, this mode allows you to use Auto-GPT solely with GPT-4.\nThis may give your bot increased intelligence.\n\n``` shell\n./run.sh --gpt4only\n```\n\n!!! warning\n    Since GPT-4 is more expensive to use, running Auto-GPT in GPT-4-only mode will\n    increase your API costs.\n\n## Logs\n\nActivity and error logs are located in the `./output/logs`\n\nTo print out debug logs:\n\n``` shell\n./run.sh --debug\n```\n\n## Disabling Command Categories\n\nIf you want to selectively disable some command groups, you can use the `DISABLED_COMMAND_CATEGORIES` config in your `.env`. You can find the list of categories in your `.env.template`\n\nFor example, to disable coding related features, set it to the value below:\n\n```ini\nDISABLED_COMMAND_CATEGORIES=autogpt.commands.analyze_code,autogpt.commands.execute_code,autogpt.commands.git_operations,autogpt.commands.improve_code,autogpt.commands.write_tests\n```\n"
  },
  {
    "path": "main.py",
    "content": "from autogpt import main\n"
  },
  {
    "path": "mkdocs.yml",
    "content": "site_name: Auto-GPT\nsite_url: https://docs.agpt.co/\nrepo_url: https://github.com/Significant-Gravitas/Auto-GPT\nnav:\n  - Home: index.md\n  - Setup: setup.md\n  - Usage: usage.md\n  - Plugins: plugins.md\n  - Configuration:\n    - Search: configuration/search.md\n    - Memory: configuration/memory.md\n    - Voice: configuration/voice.md\n    - Image Generation: configuration/imagegen.md\n\n  - Contributing:\n    - Contribution guide: contributing.md\n    - Running tests: testing.md\n    - Code of Conduct: code-of-conduct.md\n\n  - Challenges:\n    - Introduction: challenges/introduction.md\n    - List of Challenges:\n      - Memory:\n        - Introduction: challenges/memory/introduction.md\n        - Memory Challenge A: challenges/memory/challenge_a.md\n        - Memory Challenge B: challenges/memory/challenge_b.md\n  - Submit a Challenge: challenges/submit.md\n  - Beat a Challenge: challenges/beat.md\n\n  - License: https://github.com/Significant-Gravitas/Auto-GPT/blob/master/LICENSE\n\ntheme: readthedocs\n\nmarkdown_extensions:\n  admonition:\n  codehilite:\n  pymdownx.keys:\n"
  },
  {
    "path": "pyproject.toml",
    "content": "[build-system]\nrequires = [\"hatchling\"]\nbuild-backend = \"hatchling.build\"\n\n[project]\nname = \"agpt\"\nversion = \"0.3.0\"\nauthors = [\n  { name=\"Torantulino\", email=\"support@agpt.co\" },\n]\nreadme = \"README.md\"\nrequires-python = \">=3.10\"\nclassifiers = [\n    \"Programming Language :: Python :: 3\",\n    \"License :: OSI Approved :: MIT License\",\n    \"Operating System :: OS Independent\",\n]\ndescription = \"An open-source attempt to make GPT-4 autonomous\"\n\n[project.urls]\n\"Homepage\" = \"https://github.com/Significant-Gravitas/Auto-GPT\"\n\"Bug Tracker\" = \"https://github.com/Significant-Gravitas/Auto-GPT\"\n\n[tool.black]\nline-length = 88\ntarget-version = ['py310']\ninclude = '\\.pyi?$'\npackages = [\"autogpt\"]\nextend-exclude = '.+/(dist|.venv|venv|build)/.+'\n\n\n[tool.isort]\nprofile = \"black\"\nmulti_line_output = 3\ninclude_trailing_comma = true\nforce_grid_wrap = 0\nuse_parentheses = true\nensure_newline_before_comments = true\nline_length = 88\nsections = [\n    \"FUTURE\",\n    \"STDLIB\",\n    \"THIRDPARTY\",\n    \"FIRSTPARTY\",\n    \"LOCALFOLDER\"\n]\nskip = '''\n    .tox\n    __pycache__\n    *.pyc\n    .env\n    venv*/*\n    .venv/*\n    reports/*\n    dist/*\n\n'''\n"
  },
  {
    "path": "requirements.txt",
    "content": "beautifulsoup4>=4.12.2\ncolorama==0.4.6\ndistro==1.8.0\nopenai==0.27.2\nplaysound==1.2.2\npython-dotenv==1.0.0\npyyaml==6.0\nreadability-lxml==0.8.1\nrequests\ntiktoken==0.3.3\ngTTS==2.3.1\ndocker\nduckduckgo-search\ngoogle-api-python-client #(https://developers.google.com/custom-search/v1/overview)\npinecone-client==2.2.1\nredis\norjson==3.8.10\nPillow\nselenium==4.1.4\nwebdriver-manager\njsonschema\ntweepy\nclick\ncharset-normalizer>=3.1.0\nspacy>=3.0.0,<4.0.0\nen-core-web-sm @ https://github.com/explosion/spacy-models/releases/download/en_core_web_sm-3.5.0/en_core_web_sm-3.5.0-py3-none-any.whl\n\n##Dev\ncoverage\nflake8\nnumpy\npre-commit\nblack\nisort\ngitpython==3.1.31\nauto-gpt-plugin-template\nmkdocs\npymdown-extensions\n\n\n# OpenAI and Generic plugins import\nopenapi-python-client==0.13.4\n\n# Items below this point will not be included in the Docker Image\n\n# Testing dependencies\npytest\nasynctest\npytest-asyncio\npytest-benchmark\npytest-cov\npytest-integration\npytest-mock\nvcrpy\npytest-recording\n"
  },
  {
    "path": "run.bat",
    "content": "@echo off\nsetlocal enabledelayedexpansion\n\n:FindPythonCommand\nfor %%A in (python python3) do (\n    where /Q %%A\n    if !errorlevel! EQU 0 (\n        set \"PYTHON_CMD=%%A\"\n        goto :Found\n    )\n)\n\necho Python not found. Please install Python.\npause\nexit /B 1\n\n:Found\n%PYTHON_CMD% scripts/check_requirements.py requirements.txt\nif errorlevel 1 (\n    echo Installing missing packages...\n    %PYTHON_CMD% -m pip install -r requirements.txt\n)\n%PYTHON_CMD% -m autogpt %*\npause"
  },
  {
    "path": "run.sh",
    "content": "#!/bin/bash\n\nfunction find_python_command() {\n    if command -v python &> /dev/null\n    then\n        echo \"python\"\n    elif command -v python3 &> /dev/null\n    then\n        echo \"python3\"\n    else\n        echo \"Python没有找到，请安装Python.\"\n        exit 1\n    fi\n}\n\nPYTHON_CMD=$(find_python_command)\n\n$PYTHON_CMD scripts/check_requirements.py requirements.txt\nif [ $? -eq 1 ]\nthen\n    echo Installing missing packages...\n    $PYTHON_CMD -m pip install -r requirements.txt\nfi\n$PYTHON_CMD -m autogpt $@\nread -p \"按任意键继续...\""
  },
  {
    "path": "run_continuous.bat",
    "content": "@echo off\nset argument=--continuous\ncall run.bat %argument%\n"
  },
  {
    "path": "run_continuous.sh",
    "content": "#!/bin/bash\n\n./run.sh --continuous $@\n"
  },
  {
    "path": "scripts/__init__.py",
    "content": ""
  },
  {
    "path": "scripts/check_requirements.py",
    "content": "import re\nimport sys\n\nimport pkg_resources\n\n\ndef main():\n    requirements_file = sys.argv[1]\n    with open(requirements_file, \"r\") as f:\n        required_packages = [\n            line.strip().split(\"#\")[0].strip() for line in f.readlines()\n        ]\n\n    installed_packages = [package.key for package in pkg_resources.working_set]\n\n    missing_packages = []\n    for package in required_packages:\n        if not package:  # Skip empty lines\n            continue\n        package_name = re.split(\"[<>=@ ]+\", package.strip())[0]\n        if package_name.lower() not in installed_packages:\n            missing_packages.append(package_name)\n\n    if missing_packages:\n        print(\"缺少安装包:\")\n        print(\", \".join(missing_packages))\n        sys.exit(1)\n    else:\n        print(\"一切准备就绪，等待起飞.\")\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "scripts/install_plugin_deps.py",
    "content": "import os\nimport subprocess\nimport sys\nimport zipfile\nfrom pathlib import Path\n\n\ndef install_plugin_dependencies():\n    \"\"\"\n    Installs dependencies for all plugins in the plugins dir.\n\n    Args:\n        None\n\n    Returns:\n        None\n    \"\"\"\n    plugins_dir = Path(os.getenv(\"PLUGINS_DIR\", \"plugins\"))\n    for plugin in plugins_dir.glob(\"*.zip\"):\n        with zipfile.ZipFile(str(plugin), \"r\") as zfile:\n            try:\n                basedir = zfile.namelist()[0]\n                basereqs = os.path.join(basedir, \"requirements.txt\")\n                extracted = zfile.extract(basereqs, path=plugins_dir)\n                subprocess.check_call(\n                    [sys.executable, \"-m\", \"pip\", \"install\", \"-r\", extracted]\n                )\n                os.remove(extracted)\n                os.rmdir(os.path.join(plugins_dir, basedir))\n            except KeyError:\n                continue\n\n\nif __name__ == \"__main__\":\n    install_plugin_dependencies()\n"
  },
  {
    "path": "tests/__init__.py",
    "content": ""
  },
  {
    "path": "tests/conftest.py",
    "content": "from pathlib import Path\n\nimport pytest\nfrom pytest_mock import MockerFixture\n\nfrom autogpt.config import Config\nfrom autogpt.llm import ApiManager\nfrom autogpt.workspace import Workspace\n\npytest_plugins = [\"tests.integration.agent_factory\"]\n\n\n@pytest.fixture()\ndef workspace_root(tmp_path: Path) -> Path:\n    return tmp_path / \"home/users/monty/auto_gpt_workspace\"\n\n\n@pytest.fixture()\ndef workspace(workspace_root: Path) -> Workspace:\n    workspace_root = Workspace.make_workspace(workspace_root)\n    return Workspace(workspace_root, restrict_to_workspace=True)\n\n\n@pytest.fixture()\ndef config(mocker: MockerFixture, workspace: Workspace) -> Config:\n    config = Config()\n\n    # Do a little setup and teardown since the config object is a singleton\n    mocker.patch.multiple(\n        config,\n        workspace_path=workspace.root,\n        file_logger_path=workspace.get_path(\"file_logger.txt\"),\n    )\n    yield config\n\n\n@pytest.fixture()\ndef api_manager() -> ApiManager:\n    if ApiManager in ApiManager._instances:\n        del ApiManager._instances[ApiManager]\n    return ApiManager()\n"
  },
  {
    "path": "tests/context.py",
    "content": "import os\nimport sys\n\n# Add the scripts directory to the path so that we can import the browse module.\nsys.path.insert(\n    0, os.path.abspath(os.path.join(os.path.dirname(__file__), \"../scripts\"))\n)\n"
  },
  {
    "path": "tests/integration/__init__.py",
    "content": ""
  },
  {
    "path": "tests/integration/agent_factory.py",
    "content": "import pytest\n\nfrom autogpt.agent import Agent\nfrom autogpt.commands.command import CommandRegistry\nfrom autogpt.config import AIConfig, Config\nfrom autogpt.memory import LocalCache, NoMemory, get_memory\nfrom autogpt.prompts.prompt import DEFAULT_TRIGGERING_PROMPT\nfrom autogpt.workspace import Workspace\n\n\n@pytest.fixture\ndef agent_test_config(config: Config):\n    was_continuous_mode = config.continuous_mode\n    was_temperature = config.temperature\n    config.set_continuous_mode(True)\n    config.set_temperature(0)\n    yield config\n    config.set_continuous_mode(was_continuous_mode)\n    config.set_temperature(was_temperature)\n\n\n@pytest.fixture\ndef memory_local_cache(agent_test_config: Config):\n    was_memory_backend = agent_test_config.memory_backend\n\n    agent_test_config.set_memory_backend(\"local_cache\")\n    yield get_memory(agent_test_config, init=True)\n\n    agent_test_config.set_memory_backend(was_memory_backend)\n\n\n@pytest.fixture\ndef memory_none(agent_test_config: Config):\n    was_memory_backend = agent_test_config.memory_backend\n\n    agent_test_config.set_memory_backend(\"no_memory\")\n    yield get_memory(agent_test_config, init=True)\n\n    agent_test_config.set_memory_backend(was_memory_backend)\n\n\n@pytest.fixture\ndef browser_agent(agent_test_config, memory_none: NoMemory, workspace: Workspace):\n    command_registry = CommandRegistry()\n    command_registry.import_commands(\"autogpt.commands.file_operations\")\n    command_registry.import_commands(\"autogpt.commands.web_selenium\")\n    command_registry.import_commands(\"autogpt.app\")\n    command_registry.import_commands(\"autogpt.commands.task_statuses\")\n\n    ai_config = AIConfig(\n        ai_name=\"browse_website-GPT\",\n        ai_role=\"an AI designed to use the browse_website command to visit http://books.toscrape.com/catalogue/meditations_33/index.html, answer the question 'What is the price of the book?' and write the price to a file named \\\"browse_website.txt\\\", and use the task_complete command to complete the task.\",\n        ai_goals=[\n            \"Use the browse_website command to visit http://books.toscrape.com/catalogue/meditations_33/index.html and answer the question 'What is the price of the book?'\",\n            'Write the price of the book to a file named \"browse_website.txt\".',\n            \"Use the task_complete command to complete the task.\",\n            \"Do not use any other commands.\",\n        ],\n    )\n    ai_config.command_registry = command_registry\n\n    system_prompt = ai_config.construct_full_prompt()\n\n    agent = Agent(\n        ai_name=\"\",\n        memory=memory_none,\n        full_message_history=[],\n        command_registry=command_registry,\n        config=ai_config,\n        next_action_count=0,\n        system_prompt=system_prompt,\n        triggering_prompt=DEFAULT_TRIGGERING_PROMPT,\n        workspace_directory=workspace.root,\n    )\n\n    return agent\n\n\n@pytest.fixture\ndef writer_agent(agent_test_config, memory_none: NoMemory, workspace: Workspace):\n    command_registry = CommandRegistry()\n    command_registry.import_commands(\"autogpt.commands.file_operations\")\n    command_registry.import_commands(\"autogpt.app\")\n    command_registry.import_commands(\"autogpt.commands.task_statuses\")\n\n    ai_config = AIConfig(\n        ai_name=\"write_to_file-GPT\",\n        ai_role=\"an AI designed to use the write_to_file command to write 'Hello World' into a file named \\\"hello_world.txt\\\" and then use the task_complete command to complete the task.\",\n        ai_goals=[\n            \"Use the write_to_file command to write 'Hello World' into a file named \\\"hello_world.txt\\\".\",\n            \"Use the task_complete command to complete the task.\",\n            \"Do not use any other commands.\",\n        ],\n    )\n    ai_config.command_registry = command_registry\n\n    triggering_prompt = (\n        \"Determine which next command to use, and respond using the\"\n        \" format specified above:\"\n    )\n    system_prompt = ai_config.construct_full_prompt()\n\n    agent = Agent(\n        ai_name=\"\",\n        memory=memory_none,\n        full_message_history=[],\n        command_registry=command_registry,\n        config=ai_config,\n        next_action_count=0,\n        system_prompt=system_prompt,\n        triggering_prompt=triggering_prompt,\n        workspace_directory=workspace.root,\n    )\n\n    return agent\n\n\n@pytest.fixture\ndef memory_management_agent(\n    agent_test_config, memory_local_cache, workspace: Workspace\n):\n    command_registry = CommandRegistry()\n    command_registry.import_commands(\"autogpt.commands.file_operations\")\n    command_registry.import_commands(\"autogpt.app\")\n    command_registry.import_commands(\"autogpt.commands.task_statuses\")\n\n    ai_config = AIConfig(\n        ai_name=\"Follow-Instructions-GPT\",\n        ai_role=\"an AI designed to read the instructions_1.txt file using the read_file method and follow the instructions in the file.\",\n        ai_goals=[\n            \"Use the command read_file to read the instructions_1.txt file\",\n            \"Follow the instructions in the instructions_1.txt file\",\n        ],\n    )\n    ai_config.command_registry = command_registry\n\n    system_prompt = ai_config.construct_full_prompt()\n\n    agent = Agent(\n        ai_name=\"\",\n        memory=memory_local_cache,\n        full_message_history=[],\n        command_registry=command_registry,\n        config=ai_config,\n        next_action_count=0,\n        system_prompt=system_prompt,\n        triggering_prompt=DEFAULT_TRIGGERING_PROMPT,\n        workspace_directory=workspace.root,\n    )\n\n    return agent\n\n\n@pytest.fixture\ndef get_company_revenue_agent(\n    agent_test_config, memory_local_cache, workspace: Workspace\n):\n    command_registry = CommandRegistry()\n    command_registry.import_commands(\"autogpt.commands.file_operations\")\n    command_registry.import_commands(\"autogpt.app\")\n\n    ai_config = AIConfig(\n        ai_name=\"Get-CompanyRevenue\",\n        ai_role=\"an autonomous agent that specializes in finding the reported revenue of a company.\",\n        ai_goals=[\n            \"Write the revenue of Tesla in 2022 to a file. You should write the number without commas and you should not use signs like B for billion and M for million.\",\n        ],\n    )\n    ai_config.command_registry = command_registry\n\n    system_prompt = ai_config.construct_full_prompt()\n    Config().set_continuous_mode(False)\n    agent = Agent(\n        ai_name=\"Get-CompanyRevenue\",\n        memory=memory_local_cache,\n        full_message_history=[],\n        command_registry=command_registry,\n        config=ai_config,\n        next_action_count=0,\n        system_prompt=system_prompt,\n        triggering_prompt=DEFAULT_TRIGGERING_PROMPT,\n        workspace_directory=workspace.root,\n    )\n\n    return agent\n"
  },
  {
    "path": "tests/integration/agent_utils.py",
    "content": "import concurrent.futures\n\nfrom autogpt.agent.agent import Agent\n\n\ndef run_interaction_loop(agent: Agent, timeout: float | None):\n    with concurrent.futures.ThreadPoolExecutor() as executor:\n        future = executor.submit(agent.start_interaction_loop)\n        try:\n            result = future.result(timeout=timeout)\n        except concurrent.futures.TimeoutError:\n            assert False, f\"The process took longer than {timeout} seconds to complete.\"\n"
  },
  {
    "path": "tests/integration/cassettes/test_llm_utils/test_get_ada_embedding.yaml",
    "content": "interactions:\n- request:\n    body: '{\"input\": [[1985]], \"model\": \"text-embedding-ada-002\", \"encoding_format\":\n      \"base64\"}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '83'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/embeddings\n  response:\n    body:\n      string: !!binary |\n        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\n        //mv/wMAAP//AwDOXgQl4SAAAA==\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7c09bf823fb50b70-AMS\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Mon, 01 May 2023 17:29:41 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-organization:\n      - user-kd1j0bcill5flig1m29wdaof\n      openai-processing-ms:\n      - '69'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3000'\n      x-ratelimit-remaining-requests:\n      - '2999'\n      x-ratelimit-reset-requests:\n      - 20ms\n      x-request-id:\n      - 555d4ffdb6ceac9f62f60bb64d87170d\n    status:\n      code: 200\n      message: OK\nversion: 1\n"
  },
  {
    "path": "tests/integration/cassettes/test_llm_utils/test_get_ada_embedding_large_context.yaml",
    "content": "interactions:\n- request:\n    body: '{\"input\": [[5289, 564, 71, 773, 89, 2332, 19747, 87, 664, 71, 8311, 85,\n      392, 25299, 11032, 940, 89, 85, 398, 80, 73, 5481, 48558, 86, 1919, 1634, 8890,\n      5346, 44185, 53060, 450, 392, 68273, 64145, 511, 77, 80, 3696, 71, 2042, 28990,\n      44490, 19456, 89, 21807, 44490, 6331, 3180, 23361, 71, 455, 76, 583, 87, 21436,\n      34695, 352, 70, 953, 278, 59524, 2857, 93000, 641, 6043, 73, 70, 36463, 7141,\n      21807, 391, 1273, 8536, 566, 71, 7513, 580, 263, 936, 10333, 86, 983, 822, 9700,\n      73, 3316, 80, 1320, 365, 27278, 564, 67, 12591, 3576, 36851, 2465, 1739, 657,\n      6375, 89, 23361, 6885, 352, 88, 14046, 292, 70, 32204, 648, 300, 73, 32547,\n      869, 20854, 28679, 89, 11805, 70, 9081, 80, 11251, 87, 28679, 6194, 85, 906,\n      64, 300, 16501, 70494, 6511, 51622, 87, 80, 8462, 295, 13536, 49463, 604, 64,\n      333, 79, 302, 5469, 36068, 267, 5289, 19870, 911, 71, 587, 4912, 32868, 64087,\n      22650, 89, 3368, 83, 50798, 391, 273, 365, 72, 1233, 604, 3858, 48380, 710,\n      6375, 93000, 3013, 427, 7796, 66, 11160, 77, 10910, 85, 4777, 5969, 276, 7717,\n      87, 71, 21325, 80, 73389, 3576, 86, 29238, 544, 1026, 31019, 20218, 3524, 64,\n      7270, 7783, 80, 1498, 77, 1739, 5979, 327, 49450, 1791, 36409, 86, 582, 894,\n      73, 85, 89, 2174, 87, 40494, 20824, 40078, 89, 80, 4317, 1609, 85, 3601, 73,\n      86, 36068, 894, 56871, 89, 4680, 67, 2562, 1494, 6331, 16017, 2332, 21046, 86,\n      11823, 18854, 85, 10616, 85, 23913, 73, 86682, 441, 1494, 360, 1978, 3013, 2562,\n      511, 86, 427, 5298, 81, 2580, 89835, 14694, 86, 3059, 26738, 65736, 84, 1394,\n      4458, 677, 85, 3368, 71, 15479, 391, 713, 35531, 566, 94869, 325, 14029, 52360,\n      80, 406, 1290, 10616, 79, 773, 3315, 365, 89, 73, 2111, 13045, 73, 89, 14694,\n      710, 95210, 1804, 79, 20824, 80, 4086, 19555, 936, 1091, 301, 936, 1494, 73,\n      10784, 1029, 77, 1302, 1310, 86, 80, 24752, 89, 73, 89, 1302, 343, 38977, 324,\n      25457, 9902, 88, 4168, 67, 3841, 953, 96518, 4777, 3696, 80, 61057, 90563, 80,\n      20127, 86, 3418, 24672, 80, 796, 88, 85, 1026, 80, 8910, 285, 7864, 406, 14694,\n      454, 361, 85245, 83, 664, 43210, 3368, 27278, 9832, 89, 5010, 89, 762, 86, 19747,\n      299, 23808, 69057, 80, 4922, 20211, 71, 73, 404, 89, 1395, 830, 939, 5298, 402,\n      83, 80, 70, 1631, 97582, 3306, 7387, 73, 89, 2034, 66, 3906, 53060, 339, 343,\n      582, 2465, 80, 52926, 2642, 1739, 69057, 3906, 13649, 85, 3178, 291, 66, 267,\n      67910, 24672, 2201, 2933, 34175, 4777, 23361, 10784, 73, 764, 1517, 87, 12825,\n      49755, 24752, 89, 265, 307, 85, 80, 689, 332, 1331, 76, 1031, 1658, 325, 2303,\n      36851, 87, 8892, 365, 87, 402, 17606, 80, 12407, 4341, 85, 78498, 370, 3074,\n      455, 44183, 79224, 830, 20811, 906, 361, 73, 2580, 80, 359, 258, 10753, 2329,\n      37406, 50139, 67702, 10616, 56029, 7513, 2438, 402, 3258, 80, 22491, 4748, 359,\n      41129, 2034, 11032, 1658, 65, 3714, 65, 1919, 40153, 363, 2580, 52333, 73, 87,\n      80, 45015, 4086, 3141, 69, 392, 76, 19747, 21486, 708, 88, 1273, 21486, 85,\n      764, 67, 16373, 4223, 641, 53060, 784, 8977, 73, 85, 1739, 6043, 321, 89, 18571,\n      49450, 32589, 450, 88, 2303, 62497, 49595, 80, 49755, 1494, 80, 302, 2689, 87,\n      29238, 89, 1551, 8088, 76, 20926, 87, 2034, 66, 785, 22873, 53060, 8480, 708,\n      88, 906, 73, 4680, 80, 22119, 89, 398, 78498, 1919, 67, 64087, 318, 24409, 869,\n      754, 20990, 1498, 23760, 648, 728, 89, 22619, 29224, 1216, 2933, 85, 1386, 8587,\n      7737, 87, 17043, 24990, 70561, 47171, 6375, 67, 1073, 85, 89835, 3933, 85407,\n      564, 38359, 3647, 60338, 89, 17008, 10079, 80, 385, 1394, 32837, 1247, 14170,\n      74, 936, 1658, 87, 73, 365, 73, 21807, 76, 50139, 2629, 20568, 80, 1609, 5241,\n      21206, 96518, 301, 36722, 2249, 74, 581, 75, 641, 1494, 31019, 6780, 967, 361,\n      288, 77, 49755, 1631, 73, 11160, 20990, 876, 4511, 69, 675, 78, 352, 15809,\n      363, 65, 9110, 20990, 2034, 82, 544, 28546, 939, 73, 37227, 266, 70, 3013, 7911,\n      365, 14625, 65, 3841, 62559, 69, 2658, 76, 2302, 41922, 383, 347, 75, 3172,\n      784, 634, 89, 26554, 74, 75406, 544, 71, 1146, 20926, 10784, 32589, 71, 894,\n      64, 2319, 10784, 509, 15720, 327, 2701, 45015, 89, 344, 9810, 71, 344, 29700,\n      2194, 5308, 303, 85, 23361, 402, 86, 939, 283, 6870, 2005, 73, 1919, 5308, 858,\n      18854, 74, 11032, 911, 65, 80, 10784, 3576, 4223, 5289, 69, 2249, 37406, 44508,\n      89, 2739, 80, 70, 80, 10462, 80, 23001, 31019, 80, 40429, 9092, 19072, 80, 56102,\n      15444, 598, 30986, 85, 23866, 3933, 67, 1494, 86, 21325, 73, 2580, 18571, 675,\n      19239, 876, 352, 24990, 87, 1336, 14029, 78, 762, 9258, 2319, 9081, 87, 24244,\n      50536, 15720, 668, 85, 359, 86, 652, 70, 73, 70, 675, 355, 1725, 3696, 65941,\n      295, 93797, 9081, 1273, 49891, 830, 581, 360, 302, 89, 14878, 87, 80, 73, 44067,\n      86, 80, 5544, 49450, 7141, 65, 2465, 70, 344, 49463, 303, 10616, 3172, 906,\n      74, 1658, 9832, 88564, 65, 80, 1216, 69, 89, 58153, 9832, 85, 4168, 32204, 2067,\n      2465, 773, 73, 28774, 89, 5308, 18571, 49463, 300, 664, 14694, 3178, 71, 38844,\n      80, 876, 13423, 65, 1146, 87, 34175, 327, 1394, 68916, 302, 74, 78498, 22016,\n      450, 65, 2005, 7141, 80, 352, 31764, 73, 49865, 641, 16684, 17692, 2067, 9697,\n      28679, 73, 85514, 80, 337, 1804, 939, 84, 80, 906, 15618, 69, 8671, 894, 385,\n      89, 318, 13028, 18458, 70391, 89, 12328, 89, 5010, 49404, 285, 764, 32868, 3423,\n      70, 5192, 73, 70, 80, 24244, 566, 3172, 346, 31764, 89, 1273, 75, 3427, 87,\n      80, 38361, 1631, 4714, 78930, 21807, 24990, 40078, 86, 3906, 1310, 70, 406,\n      80, 360, 1100, 87, 2032, 73, 49865, 668, 37406, 6358, 24244, 6634, 265, 1100,\n      64, 16711, 822, 80, 52926, 8910, 3059, 1247, 4922, 87, 24244, 16400, 1729, 70,\n      1320, 427, 85, 355, 22524, 42908, 1729, 8510, 80, 89, 26929, 1897, 5230, 363,\n      80, 858, 89, 80, 64087, 637, 80, 48480, 69, 18577, 2303, 307, 818, 41129, 953,\n      66, 2912, 2067, 73, 822, 8671, 1247, 22619, 1073, 383, 67665, 8212, 752, 10759,\n      23866, 71, 1026, 89, 26929, 50139, 71, 16274, 8462, 82, 764, 391, 318, 74, 2465,\n      9832, 3013, 713, 16400, 89, 1065, 86, 39911, 74, 773, 81, 2042, 77, 1029, 9701,\n      22524, 80, 24672, 71, 22619, 76, 65653, 2034, 73, 581, 4748, 17008, 1320, 6634,\n      1498, 85, 80, 73, 85, 402, 67800, 637, 77, 820, 302, 12082, 4657, 831, 437,\n      74, 31881, 89, 11328, 9117, 80, 6358, 343, 363, 5964, 65, 546, 85, 32478, 1498,\n      87, 84, 454, 295, 3933, 88, 762, 1394, 69, 677, 96518, 88, 25299, 1098, 764,\n      3919, 447, 82649, 3423, 70, 566, 2249, 89, 302, 2201, 88, 983, 1498, 1320, 333,\n      3368, 34175, 84, 392, 87, 71, 16400, 93000, 8186, 27752, 74, 2465, 2642, 7141,\n      74, 11823, 11927, 80, 18499, 454, 85, 9907, 1662, 4171, 12273, 2706, 36325,\n      89, 7387, 65, 4922, 20926, 89, 23576, 73, 27515, 80, 86611, 9991, 333, 343,\n      2881, 20990, 3423, 540, 74, 796, 3013, 89, 85, 36068, 14485, 10056, 14878, 27515,\n      2465, 1026, 89, 2332, 303, 76, 28927, 43210, 3306, 81, 1658, 3576, 327, 292,\n      76627, 3415, 351, 75, 447, 89, 2302, 291, 75, 4086, 53289, 21703, 89, 392, 2042,\n      677, 3013, 70, 73, 784, 89, 14878, 6358, 81, 17156, 78, 582, 24752, 9996, 68054,\n      2312, 18571, 906, 830, 76, 344, 263, 87, 4680, 83, 12498, 65019, 4912, 65, 346,\n      10644, 75, 9902, 45228, 564, 73, 13423, 6331, 39911, 24235, 774, 74, 6789, 85,\n      1919, 441, 4748, 273, 28679, 25299, 41922, 1073, 68475, 18571, 3978, 89, 675,\n      66, 1897, 361, 37406, 9810, 53835, 66467, 87, 74, 1729, 894, 61057, 564, 81,\n      27515, 728, 86, 2562, 652, 73, 1336, 2739, 675, 71, 1897, 869, 677, 675, 86,\n      41796, 73, 637, 80, 24752, 2319, 1498, 8671, 28996, 13671, 9110, 375, 450, 1347,\n      69, 689, 72, 1100, 51318, 1609, 2042, 69, 303, 3933, 69, 1347, 8318, 86, 3647,\n      74, 710, 85, 4680, 24012, 278, 89, 70, 788, 7911, 28679, 70226, 41796, 2174,\n      57208, 11328, 292, 5308, 21888, 13536, 5308, 982, 65, 375, 820, 564, 32962,\n      8998, 2438, 74, 15479, 51622, 8587, 283, 2303, 67, 2857, 347, 372, 11823, 65,\n      303, 631, 77118, 92216, 3696, 65, 80, 2329, 4341, 74, 6200, 73, 70, 12591, 87,\n      80, 39911, 9902, 1320, 7387, 838, 56871, 61318, 86, 34175, 12328, 46082, 73,\n      87, 4341, 75406, 36825, 80, 16284, 12940, 13752, 70, 73, 88, 5544, 67, 75092,\n      30683, 80, 566, 65, 675, 84, 70678, 375, 511, 70, 74, 50900, 2465, 88, 9081,\n      70, 324, 80546, 7387, 24672, 7501, 87, 4511, 38977, 69, 73, 27278, 303, 2025,\n      5979, 4317, 915, 14170, 80, 9978, 12825, 32204, 1310, 14878, 89, 13423, 11032,\n      27515, 13536, 80, 7369, 86, 339, 14878, 89, 28531, 2303, 8587, 73, 85514, 501,\n      80, 501, 427, 4777, 45228, 939, 85, 774, 87, 6789, 4867, 19456, 71, 6885, 455,\n      75, 728, 65, 303, 675, 81, 3172, 72, 20629, 72, 587, 302, 86, 89, 3696, 86,\n      8480, 49463, 869, 295, 73, 385, 80, 73, 1658, 13183, 87, 94908, 8480, 3601,\n      1546, 99355, 66, 6194, 5192, 77, 376, 73, 88, 1729, 85, 329, 19285, 31268, 406,\n      641, 1463, 76, 392, 27780, 10470, 347, 1029, 22524, 376, 69, 22016, 86, 784,\n      288, 36851, 85407, 10056, 87, 6870, 9092, 292, 84, 1354, 70, 604, 723, 876,\n      80, 51759, 1320, 4922, 2171, 66, 22119, 85590, 85, 365, 65, 12328, 69, 283,\n      73, 86, 67800, 713, 309, 5308, 8892, 84, 554, 2329, 60933, 80, 74, 332, 86,\n      5308, 2042, 83, 652, 39152, 275, 69, 8783, 73, 28774, 24672, 87, 3893, 370,\n      79, 1662, 81, 24752, 3178, 20824, 71, 31019, 80, 78, 80, 21659, 1026, 301, 675,\n      2701, 76, 8671, 51622, 4214, 8311, 87, 80, 295, 12825, 89, 303, 5964, 92512,\n      784, 74, 99066, 31019, 97523, 454, 93000, 8671, 581, 50922, 80, 634, 77, 3893,\n      18854, 19239, 18631, 75, 50139, 7488, 455, 41129, 7453, 80, 4171, 86, 16618,\n      25105, 4341, 10776, 5683, 360, 9810, 89835, 1791, 31881, 70, 7050, 34106, 12825,\n      17134, 983, 27515, 74, 34175, 8050, 7488, 10910, 84, 354, 299, 2332, 87, 18244,\n      85, 441, 710, 13423, 2332, 70, 2032, 68, 2319, 73, 89, 764, 1604, 35555, 39152,\n      40078, 8050, 73, 2234, 65, 575, 1800, 38361, 73, 10616, 14878, 49450, 3919,\n      20369, 6375, 1725, 86, 8462, 325, 49755, 347, 83, 73, 87, 7513, 89, 830, 12328,\n      71, 8890, 97523, 303, 1631, 83, 70391, 29684, 1031, 87, 752, 31881, 1320, 4239,\n      1347, 784, 49450, 3576, 6591, 70494, 664, 2203, 2329, 86, 80, 36708, 80, 70981,\n      85, 1764, 80, 7047, 796, 78, 1073, 263, 7501, 450, 375, 16820, 73, 1310, 25457,\n      80, 7488, 65019, 1026, 355, 73, 14606, 89, 325, 295, 447, 73, 291, 69, 89, 36238,\n      911, 66, 14092, 3013, 344, 77, 398, 4086, 88, 12412, 53835, 7387, 66, 1551,\n      87, 73, 604, 73873, 1631, 1517, 318, 13009, 74, 376, 89, 8050, 664, 4193, 2000,\n      87, 74, 4086, 454, 8890, 73, 89, 32547, 3919, 10333, 554, 63643, 89, 327, 80,\n      784, 88, 3988, 13884, 664, 73, 88, 22119, 10196, 80, 8088, 41796, 343, 85, 28679,\n      65, 8998, 11032, 1662, 361, 56029, 3368, 36851, 72245, 2034, 14878, 87, 2319,\n      69, 73, 4942, 80, 70, 34097, 67, 406, 62497, 17156, 869, 1546, 7141, 10616,\n      80, 1729, 87, 68156, 1662, 10630, 4922, 15930, 11160, 55109, 74, 25299, 73,\n      59524, 579, 12825, 86, 822, 454, 77, 4171, 58305, 1517, 12498, 77584, 5192,\n      31764, 3716, 675, 383, 21486, 291, 8998, 11823, 321, 19639, 8587, 309, 66565,\n      3635, 3013, 89, 906, 3418, 7759, 18894, 89, 762, 275, 1658, 3933, 398, 22016,\n      337, 747, 2249, 56029, 566, 94869, 2249, 4458, 670, 65, 16220, 89, 8050, 8587,\n      85, 80, 301, 74, 511, 266, 79, 6194, 331, 87, 540, 6410, 1494, 1273, 4484, 4341,\n      1073, 283, 11377, 84, 3935, 89470, 80, 70, 292, 76, 1105, 2642, 20824, 87, 32837,\n      303, 12825, 4942, 406, 80, 74901, 44067, 89, 21206, 15618, 1065, 77, 2445, 2580,\n      73384, 5010, 38181, 1065, 354, 77, 5972, 664, 82999, 689, 2302, 1910, 74, 1791,\n      258, 1810, 71, 7006, 85, 953, 8587, 80, 501, 377, 77, 2739, 361, 25123, 54761,\n      2005, 307, 96518, 22619, 1494, 76, 1146, 18442, 14878, 2201, 30148, 11949, 85,\n      13092, 728, 1065, 30506, 29684, 14878, 13183, 14878, 65, 8088, 86, 19870, 86,\n      544, 85, 11160, 1498, 69, 89, 5104, 71137, 28774, 331, 1031, 79, 91410, 80,\n      29224, 49450, 93000, 5964, 1394, 8890, 84, 80, 42908, 10176, 953, 11251, 24672,\n      87, 355, 55233, 25100, 74, 4511, 16400, 20211, 17137, 3306, 20990, 372, 13855,\n      309, 89, 47689, 2701, 1910, 20127, 363, 80, 354, 637, 9117, 329, 50864, 427,\n      80, 278, 89, 708, 343, 62369, 1302, 16400, 73, 20191, 3576, 16618, 70, 302,\n      69, 392, 8480, 764, 65, 80, 321, 377, 675, 6489, 3059, 84, 80, 85514, 4223,\n      69, 12328, 74, 6634, 6358, 17043, 1739, 89, 21807, 641, 67492, 1336, 49595,\n      4341, 17008, 710, 9701, 87, 797, 92869, 5418, 2469, 60013, 377, 564, 28679,\n      1897, 50139, 418, 87, 11253, 329, 78498, 265, 4239, 377, 2329, 20926, 49463,\n      2580, 8212, 283, 3841, 46894, 762, 86, 7047, 462, 80, 47928, 80, 1331, 85, 451,\n      20568, 80, 3172, 27093, 43210, 2445, 40078, 1026, 89, 80, 359, 75, 360, 7501,\n      5469, 710, 6358, 677, 74, 5469, 80, 5192, 71, 14029, 94055, 325, 8890, 383,\n      52333, 85, 2008, 74, 7488, 36415, 12328, 74, 713, 80, 2302, 41622, 11253, 80,\n      784, 89, 501, 4937, 21206, 89, 3013, 74, 710, 86, 564, 1065, 81, 27455, 359,\n      81, 708, 347, 70, 13183, 2554, 88472, 28679, 80, 1494, 82, 8480, 7439, 86, 652,\n      34175, 74, 13423, 39911, 455, 21807, 953, 66, 4223, 14460, 81, 38359, 93000,\n      14736, 66, 7759, 68, 3524, 336, 71, 61952, 329, 7369, 28927, 581, 77, 303, 42818,\n      331, 14606, 76, 3172, 1026, 11089, 52971, 80, 20824, 73, 16276, 6194, 89, 18577,\n      677, 70, 331, 1551, 87, 86, 7387, 773, 37406, 2411, 355, 355, 4912, 85, 80,\n      1273, 39911, 31721, 9907, 376, 20191, 406, 2249, 869, 14170, 1336, 2438, 1551,\n      1347, 8088, 86626, 80, 2303, 80, 10616, 10776, 65019, 21659, 41196, 333, 989,\n      8050, 10011, 581, 509, 67, 3714, 1026, 80, 69, 1804, 75, 13565, 31881, 89, 352,\n      87, 68054, 363, 84, 3178, 2727, 710, 42848, 77827, 2303, 72, 332, 784, 273,\n      45015, 5230, 3601, 292, 454, 36722, 566, 343, 318, 1864, 2042, 2554, 333, 44508,\n      87, 85, 48029, 20127, 3172, 953, 71, 29684, 1310, 69, 657, 12825, 34175, 329,\n      3178, 66, 2465, 80, 34175, 73, 360, 283, 73, 20211, 830, 8088, 85, 80, 17851,\n      73, 11377, 1030, 69, 1498, 85, 4086, 8050, 67, 10616, 45283, 86, 5481, 80, 38359,\n      22580, 84, 7453, 581, 830, 70, 4168, 675, 89, 70, 1919, 75, 604, 74, 664, 12591,\n      41625, 31603, 675, 52926, 35401, 17008, 39152, 581, 30407, 9802, 89, 38977,\n      6151, 86, 39749, 52767, 24672, 89, 12082, 73, 88, 4341, 73, 1026, 16400, 12825,\n      16373, 564, 4657, 80, 354, 8462, 14029, 2003, 53060, 80, 17708, 1609, 87, 959,\n      69, 754, 89, 2957, 544, 19456, 57208, 20211, 9991, 71, 18244, 74, 4355, 33863,\n      16400, 81, 10784, 69, 575, 7783, 1804, 89, 4010, 798, 5544, 1273, 69, 19456,\n      89, 7047, 4835, 65, 80, 19747, 455, 6194, 1336, 76, 75406, 3055, 587, 70, 80,\n      4086, 10776, 85, 11828, 73, 451, 42908, 2249, 73, 50139, 1336, 79, 5735, 566,\n      3906, 73, 614, 87, 86, 1302, 352, 70, 80, 302, 83, 14912, 80, 70, 20926, 23866,\n      2562, 83, 16468, 277, 10002, 2562, 15930, 73, 6780, 648, 4458, 70678, 22619,\n      76, 579, 74, 19072, 84, 566, 89, 784, 12591, 363, 47689, 383, 1263, 86, 58305,\n      371, 76, 2200, 2203, 5010, 3919, 67, 13028, 346, 582, 5241, 71, 2042, 4239,\n      73, 7783, 1729, 70391, 2249, 15930, 2727, 2005, 4912, 46341, 1216, 75406, 14736,\n      69, 332, 18596, 347, 75, 3933, 3055, 27960, 86, 89, 265, 1100, 9810, 1100, 869,\n      36238, 1804, 85, 12328, 12825, 80, 32962, 39911, 8385, 80, 93797, 14029, 77827,\n      418, 2303, 361, 65019, 954, 86746, 953, 52971, 540, 3716, 363, 89, 4680, 80,\n      8385, 318, 544, 5683, 1791, 80, 1498, 79, 316, 10196, 80, 14088, 347, 3696,\n      80, 4991, 83, 2174, 50226, 65, 89044, 17692, 7911, 80, 5104, 4381, 752, 32204,\n      1331, 66, 3306, 21486, 73, 88, 1320, 75, 20824, 87, 11823, 88, 2701, 5010, 87,\n      86, 5192, 32962, 784, 3423, 4055, 1498, 3178, 301, 80, 3716, 1216, 818, 48380,\n      8035, 285, 588, 65, 540, 15770, 83, 7387, 785, 86, 3576, 2302, 52097, 7910,\n      88, 38359, 45015, 13536, 3059, 66443, 10462, 80, 1498, 21325, 73, 1729, 4777,\n      22619, 73, 28990, 89, 29700, 3427, 728, 344, 11805, 267, 86656, 392, 7513, 831,\n      7910, 391, 33539, 9117, 300, 4341, 8783, 869, 2203, 2249, 85, 2042, 1631, 37406,\n      2329, 70, 80, 3447, 1662, 13223, 57208, 11089, 65019, 73, 10776, 81, 302, 4168,\n      1411, 450, 49712, 80, 8050, 3251, 3423, 53016, 70, 447, 86, 2117, 352, 48045,\n      17063, 86611, 1310, 89, 587, 652, 32962, 60013, 3933, 14170, 87, 1031, 97523,\n      675, 44067, 5104, 77, 45015, 333, 8050, 70, 80, 525, 404, 87, 392, 41796, 69,\n      24752, 3696, 441, 30986, 49463, 21436, 67, 7387, 44508, 87, 3055, 675, 14606,\n      69, 894, 2715, 84, 83438, 73, 5673, 6358, 354, 2445, 34854, 32547, 73, 23361,\n      5308, 4086, 1631, 1551, 68467, 77, 45015, 73, 89, 70, 6733, 447, 333, 3647,\n      66, 22119, 535, 73, 86, 1498, 86, 4080, 88, 73822, 365, 41982, 454, 20127, 80,\n      1336, 392, 830, 75, 10776, 6723, 80, 74, 2580, 51924, 40261, 2042, 19275, 983,\n      86, 869, 82, 62497, 86611, 822, 64, 5171, 73, 6292, 19571, 1302, 27093, 370,\n      79, 14773, 447, 61057, 89, 80, 70, 83256, 80, 28546, 89, 80, 85369, 28679, 74,\n      3418, 283, 74, 89, 3368, 85, 953, 87, 352, 15618, 23265, 3576, 625, 784, 65,\n      318, 1197, 359, 88, 4171, 44567, 71, 46341, 2032, 16373, 354, 88, 78498, 10910,\n      3906, 85, 354, 64087, 2445, 85, 17134, 6511, 6375, 89, 19747, 65, 80, 581, 87,\n      1289, 31721, 8934, 752, 12591, 11949, 80, 1634, 12082, 333, 89, 33863, 24990,\n      5308, 67, 3841, 12328, 44970, 73, 25457, 85, 764, 8671, 35401, 2067, 73, 42848,\n      454, 80, 89, 1347, 4835, 89, 19239, 80, 31695, 511, 8480, 309, 5308, 77, 2329,\n      22119, 73, 8890, 1411, 1273, 69, 2302, 61828, 75, 13856, 5230, 33721, 1030,\n      327, 20191, 16276, 52926, 24244, 71, 876, 76, 1658, 52971, 74, 402, 69, 418,\n      42848, 73, 6358, 38828, 28774, 302, 79566, 49463, 79, 1791, 85, 8998, 52097,\n      80, 30506, 564, 89, 641, 375, 84, 2580, 41221, 4991, 36851, 8050, 796, 2332,\n      87, 74, 18571, 906, 288, 360, 6634, 85, 80, 73, 9112, 1910, 74, 10056, 86, 85,\n      12940, 51622, 1130, 86, 16618, 344, 73, 11823, 351, 3315, 2319, 22580, 37762,\n      80, 7521, 81, 376, 79, 24286, 337, 71, 9907, 8480, 94055, 3906, 1395, 80, 69,\n      9117, 85, 41796, 18442, 71, 44508, 339, 38359, 33367, 8587, 77, 7501, 5298,\n      5241, 5701, 86, 14668, 5455, 45015, 37975, 71, 632, 8890, 27515, 28679, 2580,\n      50536, 1347, 6200, 26397, 376, 8462, 73, 998, 295, 346, 88, 20990, 18442, 87,\n      1336, 74, 17134, 87, 73, 70, 80, 14170, 87624, 85, 3696, 69, 4239, 86, 85, 40924,\n      74, 818, 69, 75406, 24244, 566, 32962, 80, 675, 73, 88, 68054, 2249, 65, 344,\n      2465, 652, 3306, 82999, 78, 7453, 363, 27278, 41287, 427, 89, 324, 1331, 484,\n      69, 2034, 3418, 652, 32962, 70, 10470, 71, 3906, 28679, 45062, 2465, 20926,\n      17008, 876, 1631, 544, 87, 14912, 27093, 18287, 85, 32204, 35734, 69, 1031,\n      73, 566, 80, 2676, 72, 5308, 42528, 17008, 3906, 60013, 33367, 28774, 85, 3315,\n      64, 316, 89835, 89, 4171, 76, 1551, 20990, 89, 316, 713, 80, 1100, 20824, 19456,\n      80, 70, 21620, 77, 8892, 12407, 455, 86, 93000, 34152, 275, 73, 10036, 9490,\n      352, 83, 6632, 278, 377, 65, 2554, 337, 309, 3919, 74901, 18442, 22506, 2580,\n      7501, 74, 80, 40229, 12825, 86, 5972, 85, 8212, 336, 3576, 6151, 80, 4942, 74,\n      87, 80, 25337, 71, 2034, 80, 3933, 5972, 13536, 11285, 38361, 89, 80, 38844,\n      89, 2562, 89, 89687, 1551, 14694, 14606, 59524, 1662, 81, 764, 278, 59524, 652,\n      3013, 747, 454, 25299, 87, 1551, 2465, 9081, 67800, 73873, 450, 339, 76627,\n      53450, 89, 65116, 511, 747, 360, 89, 677, 86, 49568, 6511, 8587, 8587, 5781,\n      9081, 89, 4168, 83, 80, 23001, 55282, 831, 10616, 406, 3633, 2249, 18854, 830,\n      80, 74, 501, 363, 3696, 1791, 85, 28927, 17207, 73, 16820, 80, 28927, 441, 89,\n      15479, 86, 327, 76, 1897, 575, 69243, 4991, 657, 70, 32589, 83079, 36463, 89,\n      2249, 677, 86, 1919, 20510, 85, 383, 20103, 352, 73, 85, 8783, 78, 80, 46341,\n      6358, 764, 78, 28679, 85, 89, 28774, 69, 33863, 20211, 93141, 2201, 71, 869,\n      76, 447, 8311, 1897, 85, 89, 80, 23361, 72801, 4748, 11949, 544, 637, 86746,\n      1910, 20211, 6200, 86, 437, 52552, 66, 60933, 1872, 14088, 501, 59524, 80, 70,\n      10056, 582, 14170, 69, 20926, 752, 1411, 91943, 14170, 89, 3172, 13423, 59524,\n      564, 343, 3172, 67702, 25299, 2034, 73, 1100, 80546, 1658, 265, 773, 65, 16400,\n      86, 830, 87, 20926, 509, 44183, 73, 299, 71, 78512, 9112, 1804, 80546, 19747,\n      80, 634, 80, 1082, 85, 5972, 13423, 266, 15618, 86, 16400, 64087, 321, 1551,\n      277, 80, 3893, 68054, 708, 68, 354, 23361, 65, 18577, 79, 2303, 73, 57208, 1910,\n      89, 17043, 1910, 302, 17063, 73, 377, 12407, 84, 7488, 55233, 50798, 398, 73,\n      10776, 49595, 80, 3632, 5308, 16276, 50676, 454, 44970, 2329, 22119, 72801,\n      2319, 70, 785, 71, 18244, 74, 28679, 87, 1072, 383, 89, 15720, 85, 1286, 8587,\n      57208, 27278, 668, 20720, 546, 3647, 73, 361, 9490, 1919, 95328, 85, 10084,\n      67, 1026, 20824, 25457, 17008, 85, 5683, 347, 343, 784, 544, 998, 2303, 25453,\n      81, 2171, 86, 441, 85, 89, 8910, 30407, 73, 3251, 70, 5469, 73, 11377, 355,\n      392, 83, 73, 6194, 87, 80, 604, 983, 3178, 87, 587, 86, 664, 47689, 269, 75,\n      80, 13637, 283, 73, 9701, 73, 9902, 4835, 41796, 4171, 74, 16400, 79939, 45015,\n      43505, 80, 17063, 85, 9112, 88, 39911, 5721, 89833, 73, 4748, 85, 5298, 14029,\n      376, 13694, 65, 4341, 2067, 76423, 89, 3251, 85407, 418, 9701, 300, 13009, 85,\n      40185, 754, 1169, 61057, 9832, 77, 1215, 87, 18571, 89, 22580, 42583, 2329,\n      85, 6331, 67, 4223, 69013, 376, 8480, 86, 1331, 56201, 5104, 983, 77, 1517,\n      65116, 45228, 983, 77, 337, 80, 81606, 65, 336, 83, 1336, 77, 564, 21068, 80,\n      9810, 85, 1336, 2562, 346, 1463, 85, 30407, 1216, 28927, 266, 58153, 7501, 869,\n      87, 44508, 94869, 302, 77, 936, 26738, 20103, 50798, 9112, 71, 1725, 4575, 33963,\n      2562, 343, 67, 3576, 17692, 76, 16400, 2465, 9907, 283, 27093, 74, 939, 339,\n      73, 89, 1725, 31881, 74, 1800, 87, 2203, 70, 3306, 785, 74, 89, 42908, 11032,\n      2857, 69, 406, 65019, 73, 613, 427, 62497, 70, 7501, 67, 4010, 89, 8998, 75,\n      2857, 84, 1509, 36825, 1631, 88, 85, 14029, 23001, 7737, 80, 5010, 41796, 10176,\n      20127, 19239, 74, 2303, 4341, 11823, 329, 77, 1031, 80, 4777, 406, 1677, 87,\n      1065, 69, 73, 283, 9907, 89, 21206, 88, 73, 22119, 23866, 80, 3251, 73, 49865,\n      652, 728, 55442, 392, 86746, 7737, 85, 49755, 351, 14172, 83470, 3423, 74, 3919,\n      23048, 1889, 80, 70, 20553, 89, 3601, 307, 49463, 2067, 509, 53060, 773, 10002,\n      86, 32589, 544, 75, 59524, 11823, 486, 88, 73, 1662, 301, 7387, 344, 360, 86,\n      24468, 677, 42528, 360, 85, 1310, 70, 74, 2438, 1897, 89, 278, 41796, 3696,\n      86746, 22619, 85, 2067, 69, 73, 88, 23361, 84, 8587, 983, 2332, 80, 450, 27093,\n      88823, 8783, 73, 47689, 540, 14460, 73, 511, 90906, 69, 1026, 331, 28927, 11949,\n      30797, 1791, 76, 28927, 5298, 4777, 258, 76, 4168, 70, 540, 11032, 344, 87,\n      80, 301, 1662, 49595, 17134, 87, 80, 11160, 398, 80, 89, 6331, 77, 43686, 51622,\n      831, 1247, 88, 8892, 19639, 42426, 87, 6870, 427, 329, 3919, 65, 4080, 24752,\n      69, 1804, 3601, 3906, 1216, 23001, 7787, 36851, 20127, 1098, 316, 3433, 51622,\n      2445, 70, 5308, 7521, 85, 1029, 11927, 1091, 86, 85, 21659, 11823, 2438, 86,\n      561, 80, 10333, 7369, 331, 16276, 45228, 34175, 604, 6358, 17134, 75, 1273,\n      85, 5308, 71, 4168, 689, 21206, 2332, 19747, 20127, 10056, 1146, 2933, 49865,\n      86, 1029, 12940, 708, 5104, 73, 911, 418, 69, 2411, 88, 5308, 21888, 3906, 70391,\n      668, 46790, 80, 581, 18854, 93366, 8050, 544, 25457, 18571, 39152, 86, 1791,\n      710, 15444, 80, 4086, 13183, 329, 1631, 80, 22016, 1100, 1302, 9092, 1100, 11823,\n      689, 2580, 370, 501, 28927, 10910, 1631, 69, 5308, 69, 575, 7501, 39911, 88,\n      376, 2302, 3205, 40617, 450, 67, 33863, 511, 16820, 365, 295, 269, 677, 2329,\n      67039, 73, 7141, 4777, 7907, 3178, 58345, 2329, 56871, 273, 73, 20854, 9701,\n      48380, 86, 876, 8890, 1551, 89, 325, 23361, 49568, 86, 80, 3172, 1631, 89, 70,\n      73, 86, 8480, 89, 5192, 44508, 2392, 11823, 454, 87, 307, 2303, 75, 24990, 1551,\n      27455, 7047, 5981, 80, 1100, 869, 71, 67139, 13044, 45015, 3906, 70, 73, 9117,\n      88, 8462, 32868, 31695, 86, 80, 24244, 74, 89, 17319, 377, 69, 4511, 89, 5701,\n      48380, 876, 92562, 7387, 318, 1494, 87, 17008, 641, 7488, 71, 42510, 4922, 75,\n      49537, 8783, 42441, 24672, 66, 375, 79, 302, 42792, 6331, 80, 2302, 86, 637,\n      29238, 76736, 541, 1336, 12255, 581, 87, 427, 78498, 53904, 3919, 1347, 7387,\n      23361, 8998, 71, 43505, 80, 33495, 2302, 84, 12328, 346, 652, 89, 80, 74, 33863,\n      31881, 9117, 773, 13536, 80, 4680, 68, 295, 1725, 648, 71, 57647, 85407, 1609,\n      67, 34175, 85, 40924, 8998, 867, 5418, 710, 634, 48372, 1662, 38181, 3013, 17063,\n      19239, 73, 4239, 80, 18577, 81, 7488, 80, 1247, 70, 45015, 269, 86, 11823, 26397,\n      89, 7783, 70, 52097, 73, 876, 28990, 89, 329, 77, 80, 376, 74, 5308, 7907, 337,\n      2580, 19072, 728, 5972, 71, 402, 28679, 87, 540, 3576, 85514, 13423, 74, 2641,\n      3251, 65, 391, 32868, 89, 80, 8998, 23361, 263, 87, 7513, 87, 9092, 4010, 65,\n      5192, 266, 67175, 300, 2933, 455, 22580, 38359, 13545, 42908, 80, 85514, 6200,\n      773, 1718, 77, 2329, 7521, 3601, 17319, 73, 53289, 491, 55911, 402, 283, 89,\n      3933, 8212, 76, 675, 86, 89, 12591, 337, 4458, 347, 76, 23361, 3141, 86, 93471,\n      44183, 8587, 77, 36068, 511, 20824, 2192, 38181, 70, 14088, 81, 7501, 5485,\n      4922, 73, 70, 26397, 1072, 80, 1662, 708, 2580, 32547, 12183, 80, 20191, 89,\n      9117, 2026, 76, 2303, 86, 85, 89, 587, 73, 88, 752, 74, 1739, 318, 87, 25105,\n      9786, 89835, 1216, 1729, 87, 307, 28679, 324, 764, 89, 12407, 324, 21659, 67039,\n      23866, 73, 418, 336, 53289, 6009, 67, 3423, 4239, 564, 4763, 2689, 28844, 11949,\n      4341, 10616, 77, 23866, 1791, 65, 1662, 3628, 278, 89835, 377, 70391, 89, 14244,\n      1072, 85, 5010, 303, 1804, 6723, 80, 88, 73, 85, 604, 24752, 46224, 418, 3601,\n      771, 10616, 983, 1394, 1631, 83, 302, 38977, 74, 11328, 75, 1498, 89, 24705,\n      24244, 2067, 89, 455, 31721, 65, 7910, 86, 316, 86, 80, 17063, 5683, 1031, 27515,\n      71, 9117, 77, 1725, 2067, 32837, 2329, 85, 2438, 23001, 1136, 75611, 728, 10647,\n      79, 713, 74, 84995, 365, 361, 74452, 65019, 89, 12825, 4168, 74, 32204, 73,\n      8311, 1551, 1551, 44970, 1517, 1551, 62369, 89, 28679, 4942, 24823, 78604, 3172,\n      8783, 14029, 67, 417, 2067, 80, 73, 13536, 71, 27782, 2808, 38359, 74, 664,\n      73, 332, 764, 78604, 2312, 31268, 2739, 85, 360, 2026, 4086, 46640, 28073, 544,\n      14878, 14878, 73, 86, 70494, 27455, 8212, 19072, 73, 87, 71, 2249, 69, 4168,\n      61057, 277, 4223, 11805, 79, 39911, 3919, 83, 39911, 4341, 29700, 1729, 339,\n      86, 876, 44606, 299, 64, 3141, 83, 4942, 10776, 81, 24244, 18442, 9832, 9490,\n      80, 22016, 10616, 3315, 316, 8671, 67, 2580, 417, 31881, 15618, 278, 8088, 4168,\n      4171, 500, 89, 85, 1026, 14088, 71, 10616, 21807, 10784, 81, 2727, 14878, 52253,\n      10616, 87, 13855, 1336, 822, 336, 1247, 58305, 8318, 359, 299, 73, 87, 876,\n      38828, 1072, 84159, 10784, 96304, 455, 3906, 80, 876, 76, 8587, 31721, 5701,\n      73, 25734, 89, 752, 64, 458, 9907, 48380, 346, 45102, 12591, 62155, 20926, 93797,\n      69, 1072, 351, 87, 7141, 288, 73, 8050, 78, 831, 288, 11823, 73, 22580, 3696,\n      764, 10470, 86, 21807, 451, 5979, 324, 74, 11377, 86, 7821, 318, 299, 73, 501,\n      668, 36851, 351, 89, 80, 1804, 14606, 73, 7387, 89, 80, 21206, 17008, 89687,\n      70, 20824, 89835, 71, 1146, 2319, 1725, 22016, 21659, 80, 89, 3368, 316, 347,\n      501, 7783, 85, 70678, 894, 32868, 1498, 86, 2249, 8910, 31881, 85, 9813, 375,\n      24012, 80, 265, 1026, 21620, 303, 8207, 2641, 1029, 70, 4010, 664, 6194, 365,\n      39911, 318, 713, 89, 39911, 3933, 84, 4317, 80, 5010, 31172, 80, 24672, 68,\n      4341, 339, 69, 2857, 67, 2453, 24244, 587, 80, 38977, 53835, 31695, 351, 89,\n      455, 44067, 86, 5683, 69, 14029, 327, 2868, 69, 1065, 64, 309, 80546, 1791,\n      7141, 66, 1631, 21796, 86, 63958, 3172, 2249, 8587, 44183, 1264, 80, 17043,\n      50798, 784, 87, 22119, 39911, 10462, 80, 677, 5469, 80, 797, 2739, 7387, 80,\n      29684, 71, 2329, 31695, 789, 87, 3447, 87, 1215, 73, 1065, 19555, 89835, 32478,\n      86, 80, 3524, 822, 8311, 11823, 1029, 30243, 78498, 1662, 540, 19456, 20553,\n      2026, 80, 2438, 83079, 12498, 3696, 10188, 258, 5104, 846, 303, 70, 1919, 21807,\n      19639, 35531, 418, 21206, 3055, 4223, 351, 4010, 73, 301, 81, 73, 1517, 911,\n      36851, 337, 89, 80, 36238, 285, 46640, 20824, 1658, 21796, 42050, 2067, 263,\n      1658, 261, 641, 34175, 2580, 566, 65116, 27278, 34664, 73, 61057, 80, 9112,\n      325, 73, 5861, 2249, 7047, 48480, 10470, 2701, 79, 7513, 87, 398, 71, 2329,\n      7521, 29224, 80, 31721, 60933, 80, 581, 1631, 18894, 6375, 89, 85, 564, 86,\n      641, 89, 32547, 295, 14736, 8318, 90752, 18244, 87, 71137, 83079, 5298, 641,\n      8536, 89, 7501, 2249, 39911, 18894, 36996, 12591, 3172, 69, 488, 1347, 3368,\n      12082, 70, 80, 25457, 69, 1551, 544, 56029, 1919, 78, 80, 383, 23913, 402, 299,\n      797, 8212, 85, 1157, 7453, 73, 95945, 22473, 85, 8480, 6194, 76, 575, 365, 773,\n      91410, 32589, 89, 70, 73, 283, 71830, 20218, 9700, 1725, 344, 89, 2034, 7783,\n      2302, 74, 2642, 89, 4657, 773, 8998, 65, 7737, 269, 4575, 75593, 74, 728, 4942,\n      1347, 75, 3841, 581, 13536, 60013, 509, 46790, 80, 1073, 79, 60933, 73, 17007,\n      372, 89, 1517, 89, 383, 40952, 1002, 316, 87, 32962, 74, 392, 46341, 10616,\n      69, 3919, 31764, 4317, 773, 69, 12825, 3576, 2249, 339, 20926, 894, 12183, 89,\n      73, 15618, 8207, 76, 588, 7387, 86, 7141, 79, 11089, 8998, 84, 352, 16618, 56871,\n      89, 29443, 31764, 906, 73, 70, 44490, 450, 77, 1729, 19260, 675, 39911, 1919,\n      7513, 69, 70494, 392, 10616, 32868, 2067, 17553, 61057, 418, 5418, 80, 2784,\n      8318, 511, 77, 51622, 87, 14878, 76, 89, 2880, 64087, 9902, 1230, 80, 3576,\n      454, 2303, 41129, 3524, 89, 13752, 441, 6358, 73, 10056, 12498, 3251, 32868,\n      14736, 566, 70, 80, 4458, 752, 677, 343, 67, 376, 664, 2880, 4777, 85, 10470,\n      86, 1100, 89, 9258, 288, 48380, 16400, 668, 8512, 634, 83, 8186, 5682, 43505,\n      664, 12082, 540, 85, 26738, 80, 1725, 6009, 3141, 796, 7521, 42930, 47689, 537,\n      1302, 12329, 79, 8910, 5010, 27515, 346, 80, 89, 39911, 74, 80, 336, 7910, 80,\n      723, 462, 11160, 3919, 1073, 87, 73, 347, 637, 88, 1498, 70, 21486, 1031, 15444,\n      73, 21796, 60013, 11949, 89, 3368, 88, 69, 2329, 1551, 349, 18442, 901, 85,\n      336, 3251, 582, 2438, 48872, 450, 9081, 303, 1065, 76, 6200, 66, 1273, 581,\n      85, 22532, 1347, 76, 55506, 44970, 73, 87, 8050, 52253, 28990, 86, 6358, 48872,\n      87, 1739, 74, 89, 80, 44970, 80, 2042, 7501, 72801, 67455, 427, 16017, 85, 324,\n      31764, 1729, 78, 380, 8671, 57367, 2319, 82, 1336, 89, 15444, 73, 8376, 2315,\n      64, 454, 46640, 69057, 383, 73, 361, 80, 3059, 85, 316, 587, 86, 587, 637, 5308,\n      5298, 70, 1394, 6733, 80, 11032, 80, 8998, 8212, 73, 87, 462, 71, 45015, 86,\n      89, 8998, 34175, 69, 89, 6200, 14606, 85, 2332, 79, 876, 894, 68566, 8783, 86,\n      11345, 65, 1631, 1302, 89, 9081, 8480, 73, 5972, 8587, 80, 2445, 2026, 1017,\n      377, 88, 451, 277, 18244, 581, 336, 604, 8311, 85, 7737, 86, 89, 1031, 79, 3415,\n      73, 1609, 79, 45015, 17319, 87, 86, 13536, 939, 89, 14088, 77, 1100, 21068,\n      85, 89, 93366, 86, 4168, 2933, 73, 21206, 509, 28774, 71, 11949, 566, 6200,\n      22619, 38041, 28204, 10647, 96518, 22619, 3326, 67919, 23361, 52971, 292, 65,\n      713, 5308, 295, 76, 4867, 1568, 1729, 89, 10188, 88, 936, 300, 336, 3306, 3368,\n      1065, 9326, 65, 7387, 2465, 869, 66, 9555, 83079, 1494, 87, 3423, 652, 11805,\n      3906, 73, 70, 1910, 87, 10097, 72, 4171, 86, 8892, 24409, 80, 5230, 2554, 73,\n      52097, 80, 2026, 38977, 365, 4080, 89, 32868, 16711, 80, 352, 84, 80, 23361,\n      74, 80, 89, 66777, 773, 87, 21620, 1551, 34856, 462, 402, 27455, 8480, 55568,\n      1919, 67, 39911, 87, 3178, 67665, 80, 3601, 4080, 89, 764, 17704, 80, 324, 74,\n      9996, 80, 333, 87, 1919, 8385, 1739, 302, 4922, 14406, 830, 76, 96416, 89, 1910,\n      89, 85, 5010, 67800, 45015, 77, 16373, 89, 1804, 76, 14029, 376, 77, 23577,\n      4970, 73873, 11823, 1983, 74, 80, 3601, 67, 9092, 385, 22575, 672, 69057, 13045,\n      354, 38361, 8212, 86, 89, 4991, 8088, 71, 7197, 19239, 38041, 64087, 875, 657,\n      66, 773, 24244, 74, 4680, 9832, 74, 4890, 85, 332, 19555, 86, 2106, 77, 6151,\n      1065, 346, 5308, 969, 5104, 28679, 74, 13536, 85, 1031, 509, 75, 3172, 15802,\n      80, 5010, 75, 49450, 3933, 87, 1658, 87, 327, 47171, 21543, 34175, 87, 49358,\n      398, 31764, 55233, 392, 44508, 73, 302, 73, 36722, 12940, 71, 73, 7488, 12825,\n      89189, 37406, 52971, 3427, 4341, 3141, 876, 70, 5010, 324, 7047, 73, 2438, 3368,\n      46224, 762, 385, 73, 11949, 2203, 31764, 66, 46640, 86, 5010, 65, 2580, 89,\n      3153, 4664, 78930, 88, 1546, 398, 2034, 86, 5237, 44490, 784, 84, 263, 391,\n      2580, 85, 346, 14468, 79, 2067, 85, 42818, 18442, 8385, 677, 1662, 2067, 86,\n      383, 6723, 1073, 64145, 1026, 587, 2629, 383, 80, 8671, 40078, 953, 24990, 2026,\n      66867, 1568, 66, 1551, 8088, 38041, 74, 764, 70, 32478, 49450, 32204, 15555,\n      31146, 15809, 546, 15618, 689, 78498, 5308, 361, 73, 8462, 24738, 266, 26039,\n      71, 7910, 80, 875, 53835, 88, 28679, 73640, 17008, 70, 5308, 34146, 71, 710,\n      85, 8910, 8311, 2562, 42818, 6511, 796, 22119, 74, 87, 1394, 6200, 70, 46640,\n      47154, 89, 6151, 581, 3906, 1273, 10470, 25299, 80, 30407, 299, 6292, 266, 73,\n      63885, 1336, 20553, 1631, 86, 372, 752, 41796, 85, 336, 74, 1065, 66, 16499,\n      69, 6358, 38385, 10776, 71, 23913, 276, 80, 73, 13855, 77, 764, 68054, 23866,\n      796, 80, 1725, 4239, 71, 544, 2480, 89, 657, 86, 80, 78, 343, 73, 2603, 42511,\n      69, 69057, 5964, 7369, 8462, 14029, 261, 12989, 11949, 49463, 73, 87, 4010,\n      90231, 365, 450, 79, 29238, 85, 427, 82, 65167, 41129, 31019, 68411, 1347, 47689,\n      70678, 1551, 87, 22119, 3418, 728, 65, 80, 657, 80, 73, 10820, 1029, 80, 30506,\n      42908, 54899, 677, 451, 80, 20990, 85, 10036, 71, 2445, 20962, 708, 69, 764,\n      652, 796, 7501, 80, 1498, 78930, 5010, 10196, 80, 1072, 295, 87, 23361, 70,\n      45015, 70, 351, 67800, 86626, 66, 634, 1631, 9092, 73, 797, 87, 19866, 12498,\n      74, 3172, 70, 2303, 74, 12498, 7737, 65, 3601, 2727, 80, 360, 2034, 32204, 2727,\n      65, 1609, 5972, 89, 4680, 5981, 42818, 7501, 1302, 38977, 65019, 88, 797, 80574,\n      300, 1658, 73, 4657, 309, 97715, 5192, 6009, 24027, 10333, 84, 80, 14029, 40924,\n      2111, 67, 728, 372, 85, 365, 18854, 86, 5289, 276, 9902, 80, 359, 20553, 1804,\n      339, 8311, 1065, 370, 869, 73, 10776, 77, 80, 1764, 10333, 76, 1910, 8311, 437,\n      80, 4777, 77, 657, 74, 93000, 447, 85514, 6375, 4912, 36851, 42908, 7047, 25299,\n      74, 1273, 21436, 76731, 1658, 85, 953, 88, 9700, 5104, 36825, 544, 7513, 73,\n      438, 89, 11253, 10784, 73, 2026, 70, 74, 8207, 309, 25772, 4239, 38181, 3251,\n      65, 831, 377, 8480, 87, 22873, 83, 73, 94817, 637, 5746, 3423, 953, 65, 427,\n      41129, 89, 46224, 73, 1247, 370, 87, 300, 8248, 86, 2249, 8910, 85, 2221, 710,\n      303, 1247, 87, 86, 1331, 87, 18577, 85, 26397, 16276, 3458, 80, 2857, 377, 11251,\n      89, 7387, 42908, 302, 39911, 77, 385, 39911, 42050, 710, 89, 40078, 89835, 70,\n      5289, 344, 11328, 80, 1339, 355, 31721, 41523, 344, 2438, 73, 7501, 333, 2203,\n      540, 375, 79, 521, 5981, 588, 80, 89, 85, 10796, 87479, 8050, 73, 4239, 9988,\n      76, 1631, 81, 8088, 79, 1394, 82, 2912, 70, 73, 52513, 822, 511, 9188, 450,\n      10176, 46640, 87, 86, 398, 333, 86, 8385, 80, 300, 1897, 55773, 303, 1072, 2319,\n      89, 9996, 664, 31268, 13855, 939, 69, 27457, 39911, 911, 55748, 347, 83, 73,\n      86, 581, 6331, 370, 70, 73, 9907, 3105, 752, 78, 70391, 5298, 74, 28679, 65,\n      22524, 74, 64087, 80, 78, 3251, 28400, 1116, 80, 74, 796, 24459, 723, 85, 89,\n      3418, 344, 27515, 40078, 93797, 85, 1658, 6194, 73, 501, 2933, 71, 95143, 11206,\n      71, 73, 5079, 1073, 74, 3178, 5683, 3431, 81, 40078, 89, 1354, 73, 86, 3013,\n      303, 89, 454, 70, 80, 784, 80, 42818, 3368, 71, 7501, 67800, 85, 73445, 73976,\n      86, 5650, 6194, 79, 318, 66, 318, 12328, 65, 2200, 13536, 31019, 3059, 689,\n      3251, 6511, 80546, 564, 77, 1517, 28774, 4080, 41129, 292, 81, 783, 65, 70678,\n      24752, 73, 89, 894, 939, 39152, 566, 85, 77827, 80, 4511, 72, 1130, 5964, 20811,\n      263, 74, 339, 8910, 71, 8566, 604, 332, 1320, 16400, 307, 4763, 67665, 69, 73,\n      12591, 42050, 19072, 80, 3906, 89, 392, 73, 7488, 89, 1122, 418, 20103, 80,\n      56871, 4880, 65, 80, 74, 427, 566, 796, 77, 5701, 80, 74, 27455, 25817, 1551,\n      309, 540, 354, 94908, 8998, 4223, 14878, 8050, 23001, 87, 1065, 65, 9907, 1494,\n      1910, 581, 85514, 365, 88, 21888, 85, 5298, 998, 402, 9991, 85, 303, 299, 2496,\n      45015, 3427, 352, 74, 80, 797, 23707, 87, 13441, 365, 49891, 66, 450, 343, 26397,\n      1273, 455, 318, 267, 80, 7047, 1590, 318, 71, 20127, 564, 75, 303, 710, 5469,\n      3251, 8207, 318, 75, 10784, 2438, 79, 87348, 4168, 74, 34870, 302, 80, 3458,\n      80, 88, 50153, 1233, 86, 344, 23048, 370, 7521, 10002, 1100, 9700, 337, 20553,\n      87, 363, 9451, 6194, 73, 63643, 93000, 6511, 9110, 73, 2649, 80, 89, 80, 70,\n      9490, 86804, 87, 18577, 74, 3415, 7910, 6388, 1498, 27457, 1073, 70, 80, 69,\n      18442, 359, 58153, 73, 9907, 540, 89, 3251, 18458, 365, 5192, 74, 412, 327,\n      509, 78, 343, 73, 20127, 18442, 85, 19072, 10616, 391, 85, 80, 11160, 10056,\n      911, 24752, 4922, 86, 85, 42908, 1631, 343, 318, 89, 641, 2784, 1729, 1030,\n      5972, 15479, 1900, 2933, 43505, 2439, 9509, 728, 3978, 13536, 89, 32868, 6455,\n      2249, 8998, 89, 56871, 10784, 784, 5308, 49712, 89, 22524, 52097, 509, 45015,\n      8910, 2329, 73, 3418, 677, 4912, 80, 69, 24752, 11377, 10776, 391, 21325, 6511,\n      552, 2319, 1658, 49712, 9700, 70, 73, 8998, 80, 285, 365, 64305, 89, 61057,\n      1729, 86, 5298, 71, 544, 307, 798, 23913, 70, 2303, 263, 76, 16400, 89, 48380,\n      33323, 80, 24244, 48372, 18926, 7910, 3418, 85, 1551, 4341, 677, 44067, 3601,\n      3696, 48610, 3427, 89, 710, 10470, 587, 36722, 49463, 45015, 13009, 9700, 79,\n      372, 30987, 81964, 21796, 48380, 588, 371, 2201, 3059, 89, 55418, 47154, 73,\n      53289, 13722, 3524, 2642, 18854, 1764, 68, 16618, 80, 764, 80, 5241, 1604, 5972,\n      88, 352, 1662, 64087, 80, 4991, 10910, 953, 80, 303, 80, 1498, 376, 377, 88,\n      6634, 80, 1466, 7453, 94912, 9490, 8462, 15618, 65, 710, 89833, 75, 80, 88,\n      437, 73873, 89, 2312, 318, 66, 359, 9832, 3601, 8207, 23361, 74, 418, 67, 34175,\n      86, 80, 25457, 66, 333, 85, 3178, 1725, 268, 80, 4484, 604, 84, 4341, 5469,\n      89, 78498, 89, 35531, 67800, 4852, 441, 65, 93000, 33721, 318, 74, 604, 36851,\n      64145, 93797, 2465, 80, 61057, 302, 3316, 2191, 31019, 19456, 20824, 637, 8826,\n      21486, 351, 79, 6414, 3178, 1725, 80, 89, 42818, 80, 404, 1498, 86, 85, 588,\n      74, 634, 14088, 87, 23361, 80, 47689, 30506, 1029, 12119, 80381, 5964, 66, 1498,\n      73, 6292, 291, 89, 6256, 7835, 1498, 66, 7453, 73, 87, 19239, 582, 5308, 93529,\n      1634, 88, 329, 10616, 86746, 20191, 402, 4080, 86, 2005, 6511, 361, 74, 5308,\n      450, 66, 8462, 6780, 363, 4719, 85, 9810, 80, 29238, 80, 1910, 13855, 309, 69,\n      1498, 9092, 4922, 5418, 830, 79, 1100, 12682, 83, 73, 87, 73, 318, 66, 3423,\n      65, 80, 2332, 3906, 370, 710, 327, 28546, 87, 7488, 86, 12940, 773, 6043, 80,\n      10847, 84506, 352, 830, 65, 10616, 329, 22119, 4458, 64, 427, 79, 372, 21659,\n      31881, 3423, 44970, 1662, 1233, 8510, 31577, 81, 1031, 2308, 87, 318, 12498,\n      18299, 88, 869, 4657, 773, 339, 3841, 72, 4912, 3518, 406, 73, 3251, 65019,\n      88, 7047, 10630, 9092, 53060, 9902, 82999, 4625, 309, 38361, 67800, 16848, 70,\n      675, 42848, 87, 8671, 28990, 25604, 74470, 1662, 79, 7737, 418, 2690, 12328,\n      3893, 24672, 398, 53016, 32759, 3181, 72, 906, 652, 80, 13075, 31019, 48872,\n      96304, 5104, 637, 4381, 683, 70, 604, 1073, 625, 74, 58598, 28990, 418, 501,\n      80, 1216, 53016, 87, 43723, 66, 352, 85, 12940, 747, 404, 2026, 14170, 80, 8088,\n      1031, 967, 86, 911, 45228, 73873, 88, 1331, 581, 906, 85, 70391, 17008, 80,\n      275, 22619, 2739, 85, 16400, 4317, 80, 509, 372, 343, 21659, 2176, 80, 333,\n      1065, 9780, 73, 375, 20372, 1677, 71, 10056, 9902, 89, 5697, 336, 675, 71, 641,\n      29684, 1030, 39152, 911, 19747, 80, 32204, 1662, 1065, 4484, 89388, 1609, 3647,\n      94869, 6036, 1764, 15258, 1551, 16373, 5289, 85393, 5469, 2411, 77, 1551, 85,\n      47154, 365, 69, 26397, 76, 1026, 5544, 1494, 15618, 52971, 11089, 51622, 70391,\n      4991, 83079, 7737, 71, 450, 65, 16276, 84, 5308, 939, 24244, 9289, 89, 19072,\n      462, 1729, 11805, 36851, 329, 4010, 307, 333, 1662, 38041, 11160, 1658, 796,\n      5237, 45228, 8050, 70, 80, 10776, 9092, 1631, 363, 34175, 2070, 36068, 68054,\n      14949, 1031, 3906, 73, 13536, 71, 10470, 83448, 5010, 9092, 77, 7488, 84, 300,\n      25770, 26636, 544, 86, 4010, 22473, 8536, 3251, 76, 1286, 261, 17704, 4341,\n      70, 27455, 11872, 55568, 351, 74, 10056, 80, 12498, 70, 73, 46790, 566, 377,\n      398, 67, 1100, 376, 38361, 69, 24012, 580, 85, 80, 11851, 32589, 377, 22619,\n      316, 3576, 652, 70, 2329, 3251, 343, 2319, 82, 441, 36851, 79, 20127, 71, 1609,\n      29700, 89, 92216, 87, 398, 1517, 73, 637, 67, 5346, 71, 7501, 7141, 96518, 6098,\n      81, 418, 85, 10470, 83, 544, 41796, 89, 89835, 6358, 85, 4777, 564, 35804, 604,\n      80, 38181, 302, 95947, 70, 12723, 412, 80546, 395, 1273, 1029, 300, 87, 3368,\n      1273, 454, 74, 5972, 74, 1030, 12748, 80, 450, 20127, 5964, 69, 351, 75, 9907,\n      9092, 77827, 7063, 84, 2319, 266, 303, 365, 18577, 1073, 675, 3647, 69, 454,\n      87, 8587, 73, 85, 3893, 28679, 80, 25299, 1029, 57208, 9092, 9117, 2034, 89,\n      2689, 5972, 9991, 79, 12498, 74, 89, 29684, 2302, 29684, 76064, 89, 14694, 288,\n      98667, 7501, 80, 39172, 2005, 73, 3479, 14244, 73, 13183, 31019, 344, 360, 22016,\n      1936, 9081, 1725, 30506, 11160, 1919, 81, 42908, 80, 89, 4223, 86, 2302, 418,\n      3172, 87, 1729, 303, 80, 2329, 566, 85, 1336, 13536, 85, 44970, 9832, 73, 86,\n      302, 73, 1220, 18571, 774, 46224, 10784, 5544, 73, 4912, 1371, 12940, 1073,\n      73, 12082, 80, 1394, 53060, 437, 6043, 511, 17137, 85, 1065, 88, 4010, 7044,\n      32204, 451, 88, 7387, 6511, 1320, 283, 327, 581, 70, 33863, 23913, 89, 20824,\n      22016, 1394, 40924, 344, 89, 754, 7453, 73, 85514, 80, 2668, 575, 67, 1725,\n      675, 69, 73, 15720, 67782, 418, 69, 41796, 87, 302, 73, 54909, 10616, 2312,\n      74901, 74, 36238, 2580, 18854, 2042, 89, 399, 89, 31268, 74, 45015, 38041, 5469,\n      12498, 13391, 14029, 652, 66565, 3178, 35949, 1631, 4341, 5469, 49938, 65, 1897,\n      295, 2111, 344, 47154, 73, 2580, 73, 65019, 10333, 8462, 78, 1065, 6634, 71,\n      1804, 267, 66, 40078, 3013, 74, 6331, 355, 1729, 80, 24672, 540, 35531, 2445,\n      15008, 89, 5104, 1273, 88, 69, 1494, 1091, 2249, 88, 37975, 2857, 9832, 25299,\n      710, 70, 80, 89, 97523, 23866, 261, 89, 70678, 764, 87, 18577, 21486, 8480,\n      69468, 3841, 20926, 80, 352, 12498, 73, 42528, 36825, 301, 80, 418, 89, 45788,\n      337, 9832, 89, 85, 12498, 76, 1030, 1394, 11377, 73, 869, 728, 5241, 773, 88,\n      3340, 85, 1310, 80, 637, 4239, 30407, 3415, 68, 71696, 762, 302, 19239, 89,\n      1320, 1394, 764, 93000, 4680, 71, 2249, 69057, 501, 23760, 6200, 91998, 18400,\n      85, 20926, 7501, 73976, 79, 46390, 80, 318, 370, 18577, 343, 1725, 70, 1658,\n      4991, 96605, 73, 1029, 9832, 376, 67, 8536, 301, 89, 331, 85, 1347, 1931, 73,\n      6632, 301, 278, 46341, 784, 1725, 63643, 60013, 32589, 89, 1310, 89, 24990,\n      86, 18854, 4937, 4680, 87, 71, 483, 355, 455, 25299, 664, 67702, 1073, 9195,\n      73, 6634, 59524, 74, 80, 2739, 18854, 74, 501, 1331, 86, 26738, 391, 1073, 64145,\n      70, 2067, 359, 47875, 3251, 1498, 3933, 6780, 1739, 4912, 4223, 418, 79, 1897,\n      664, 65, 10188, 80, 983, 11823, 266, 48320, 5192, 36851, 74, 8311, 876, 15444,\n      3906, 87, 2332, 75, 80, 14878, 2465, 4835, 983, 76, 8462, 784, 5469, 575, 3013,\n      59524, 375, 12328, 73, 20127, 89, 983, 9112, 713, 324, 86, 11253, 7819, 1092,\n      86, 89, 339, 74, 15959, 295, 51924, 1073, 89, 31721, 325, 1331, 309, 85, 12407,\n      8671, 59524, 20211, 4484, 998, 283, 8318, 88, 73, 2312, 1036, 21888, 7004, 2026,\n      5241, 80, 2332, 36171, 87, 2303, 89, 26929, 1366, 20127, 71, 70678, 1551, 84,\n      773, 3806, 21206, 278, 81, 9664, 76, 38359, 85, 1394, 773, 869, 3906, 953, 347,\n      76, 1978, 383, 41622, 509, 339, 80, 17156, 266, 9117, 87, 84, 12748, 88467,\n      708, 15618, 73, 46341, 447, 48380, 80, 7208, 74, 87, 70, 73, 70, 1290, 88, 324,\n      302, 78, 336, 3306, 86, 361, 4922, 89, 73, 764, 307, 31172, 8671, 70, 283, 96518,\n      31422, 88, 73, 2159, 332, 2067, 710, 668, 8462, 31764, 70, 3013, 19271, 86,\n      657, 79, 316, 74, 447, 263, 44970, 5481, 44490, 17043, 32973, 4168, 2302, 74,\n      7501, 9832, 451, 1247, 575, 344, 2042, 1031, 81, 1739, 69417, 273, 11289, 81,\n      2445, 307, 28679, 1273, 8385, 648, 78, 511, 2445, 7047, 76188, 441, 2192, 80,\n      54803, 9700, 5308, 68054, 71, 398, 3415, 953, 88, 73, 10462, 363, 31172, 370,\n      89, 9810, 71, 1517, 52719, 84, 587, 3418, 82, 3423, 1729, 89, 876, 82, 3415,\n      73, 85, 2642, 22524, 377, 4942, 73, 564, 9700, 87, 2106, 8318, 88, 80, 22619,\n      752, 70, 1394, 75, 3178, 4835, 89, 657, 18571, 1729, 8207, 86, 89, 92216, 3172,\n      4942, 3933, 332, 939, 57208, 9991, 363, 19239, 4511, 89, 73, 347, 86, 9081,\n      70, 8587, 2580, 80, 325, 9490, 3906, 19747, 5481, 70678, 5544, 67, 34175, 29229,\n      13616, 73, 12130, 36851, 85, 80, 36068, 6200, 427, 17704, 80, 3251, 85, 31695,\n      402, 3516, 869, 74, 383, 2067, 72801, 79, 1791, 73, 939, 70, 1604, 3368, 86746,\n      87, 392, 75, 543, 4835, 88, 80, 4086, 94055, 16400, 71, 75406, 339, 625, 1729,\n      31764, 15479, 511, 1551, 5598, 398, 1320, 346, 11377, 437, 901, 85, 80, 38041,\n      73, 59448, 4223, 85, 3601, 283, 16820, 41796, 85, 4381, 336, 55498, 283, 22119,\n      14878, 44183, 455, 3059, 21538, 16017, 73, 5683, 89, 372, 708, 28927, 9832,\n      66, 98667, 752, 80, 69, 89, 1231, 8088, 11222, 1394, 3306, 71, 1517, 911, 85,\n      17134, 2302, 85, 818, 7141, 65, 5298, 70, 3601, 7521, 4355, 3223, 84, 347, 70,\n      4080, 61057, 46341, 1804, 28927, 46341, 47154, 16400, 8462, 12119, 32547, 1658,\n      12591, 20127, 12825, 84, 80, 275, 3172, 10470, 9117, 417, 73, 894, 34967, 80,\n      7488, 86, 80, 953, 2312, 17134, 86, 288, 77, 343, 10616, 25105, 29238, 74, 9110,\n      39152, 86, 1310, 76, 385, 1610, 74, 89, 9509, 61318, 77, 78498, 73, 88, 5418,\n      56178, 89, 9197, 398, 347, 55655, 25299, 5289, 3893, 25105, 675, 43210, 398,\n      65, 2329, 376, 2203, 17134, 75, 333, 89, 10910, 1336, 87, 32837, 75406, 80,\n      4010, 80, 1026, 75, 3368, 68, 55334, 42818, 80, 89, 1551, 31695, 86, 10784,\n      2329, 9701, 544, 81, 339, 20990, 10796, 75, 1094, 14606, 85, 1336, 45228, 3576,\n      336, 11949, 391, 86, 8088, 46224, 291, 36851, 424, 73, 86, 3415, 1609, 89, 4168,\n      88, 47391, 8587, 28990, 29700, 80, 3055, 402, 14928, 67, 7488, 876, 76, 6780,\n      88, 36825, 42908, 2312, 3306, 2739, 80, 25295, 30506, 501, 21066, 93000, 2562,\n      7215, 337, 80, 88, 677, 69, 33863, 80, 16820, 572, 35278, 77, 80, 1065, 64,\n      309, 77, 544, 1149, 68054, 784, 2332, 67, 2641, 73, 88, 9117, 87, 4922, 79,\n      911, 83, 10616, 11823, 275, 73, 21620, 31268, 70678, 1029, 98496, 12328, 10910,\n      79, 416, 85, 89, 664, 26397, 71, 73, 32962, 10056, 85, 17134, 1146, 80, 30463,\n      1551, 24990, 70, 41670, 604, 67702, 11032, 7488, 385, 581, 80, 1247, 11823,\n      87, 9701, 501, 1146, 352, 76, 44183, 21620, 936, 9700, 76, 1216, 76, 2396, 2249,\n      2739, 73873, 87, 18664, 88, 1919, 86, 85, 2042, 5972, 28546, 73, 86, 11089,\n      22619, 80, 99161, 1216, 45228, 2438, 70, 511, 79, 391, 25299, 939, 86, 1718,\n      80, 70, 1764, 21796, 74, 47154, 67800, 9490, 28679, 67, 365, 406, 73, 43974,\n      89, 19239, 652, 71, 73, 89, 3841, 60013, 2249, 69, 5584, 6194, 70, 80, 73, 21807,\n      58305, 329, 1029, 74, 7453, 1216, 80, 3141, 97816, 4511, 17134, 60933, 45015,\n      74, 5721, 664, 5010, 327, 74, 80, 295, 346, 89, 24527, 1331, 96250, 344, 89,\n      80, 8088, 953, 82, 2727, 318, 352, 347, 8207, 73, 88, 8462, 75, 796, 14606,\n      1662, 540, 17851, 36825, 1031, 80, 359, 1310, 11823, 566, 588, 73, 5038, 4942,\n      49595, 8462, 4942, 32204, 85, 1029, 73, 4484, 309, 9902, 85, 2857, 10784, 82969,\n      747, 88, 64087, 302, 86, 4080, 73, 87, 31764, 728, 91295, 95143, 7513, 869,\n      359, 67020]], \"model\": \"text-embedding-ada-002\", \"encoding_format\": \"base64\"}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '45399'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/embeddings\n  response:\n    body:\n      string: !!binary |\n        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\n        AAAA//8DADtB0HjnIAAA\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7c09bf85ef231c7e-AMS\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Mon, 01 May 2023 17:29:42 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-organization:\n      - user-kd1j0bcill5flig1m29wdaof\n      openai-processing-ms:\n      - '406'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3000'\n      x-ratelimit-remaining-requests:\n      - '2999'\n      x-ratelimit-reset-requests:\n      - 20ms\n      x-request-id:\n      - 3c27a4a0263197ea84526b8aa83799d6\n    status:\n      code: 200\n      message: OK\n- request:\n    body: '{\"input\": [[359, 74901, 1146, 437, 11949, 3933, 74901, 728, 86, 511, 73,\n      5241, 65116, 4991, 375, 10333, 20191, 89, 383, 22650, 1551, 327, 1810, 1804,\n      80, 347, 11089, 3013, 752, 1100, 73976, 303, 32547, 73, 3696, 3906, 77, 969,\n      455, 62615, 6581, 66, 501, 67, 2649, 12825, 8536, 89, 2067, 85, 80, 70, 74,\n      755, 74, 352, 73, 4086, 3178, 87, 80, 35401, 376, 15618, 655, 13423, 33863,\n      3933, 911, 77, 32204, 2689, 454, 29200, 2176, 1739, 65, 8998, 38844, 4223, 953,\n      14088, 21486, 1316, 12328, 1725, 21486, 24752, 86, 1394, 5308, 321, 31019, 89,\n      80, 73, 5981, 88, 69, 2249, 19072, 23576, 9110, 47154, 876, 73, 2319, 1029,\n      6292, 69057, 2857, 20191, 2329, 80, 6455, 46640, 351, 89, 5289, 876, 77584,\n      73, 2026, 84, 361, 23361, 87, 85, 4680, 85, 80, 13009, 86, 1725, 73, 641, 80,\n      45015, 85, 447, 1072, 86, 22374, 14029, 83, 28679, 73, 70, 5298, 7369, 79, 544,\n      12591, 327, 9701, 80, 2465, 84, 455, 11949, 7881, 74, 4912, 44508, 80, 5298,\n      17553, 31268, 85, 604, 77, 11032, 6331, 9490, 45444, 450, 6236, 1919, 67, 20990,\n      34175, 1804, 73, 41101, 80, 277, 73, 89, 664, 723, 49755, 80, 2191, 28531, 8587,\n      15555, 79, 675, 42818, 375, 3601, 82, 1334, 76, 89, 511, 87, 73, 318, 4080,\n      85, 1146, 80, 983, 796, 12825, 67, 4086, 78, 336, 1897, 80, 70, 11032, 7501,\n      85, 12825, 651, 79, 16017, 80, 268, 69, 4021, 15817, 3757, 16400, 652, 28679,\n      5964, 73, 17063, 80, 9907, 67039, 848, 85, 5308, 76, 657, 65, 1216, 88, 40924,\n      11949, 76, 377, 79, 1091, 258, 343, 4080, 13752, 70, 27515, 265, 1273, 85, 89,\n      44970, 71, 708, 582, 637, 1395, 1662, 83, 27457, 5308, 8942, 1498, 360, 89,\n      10002, 67, 4317, 269, 587, 86, 13616, 31268, 73873, 299, 80, 73, 14088, 455,\n      8480, 1609, 372, 53060, 48380, 17008, 48380, 35401, 40078, 45854, 652, 80, 21796,\n      1551, 89, 9832, 87, 74, 1029, 307, 61057, 85, 12498, 648, 541, 267, 89, 70,\n      24752, 80, 18577, 43210, 74, 370, 80, 830, 4341, 87, 8890, 4890, 31218, 641,\n      82, 6331, 85, 80, 14170, 71, 325, 48186, 16400, 68054, 346, 9991, 78930, 939,\n      1310, 4239, 93000, 73, 2067, 86, 11032, 43210, 8311, 80, 38768, 86, 1494, 2312,\n      92216, 41670, 13028, 48802, 89, 7369, 69, 2005, 73, 7783, 953, 85, 49450, 73,\n      1029, 402, 84274, 1026, 76, 89, 85, 664, 8088, 75163, 376, 20127, 80, 10470,\n      406, 13183, 10616, 36722, 511, 1394, 87, 60933, 1031, 76, 1540, 5308, 66, 939,\n      634, 4991, 29682, 351, 332, 4086, 19639, 15618, 16017, 49450, 73, 87, 20191,\n      10176, 80, 32204, 32589, 1116, 355, 36238, 10470, 74, 2312, 76, 60013, 375,\n      71, 55506, 87, 8671, 89, 11089, 8910, 74, 9326, 3933, 23048, 86, 441, 718, 7047,\n      75, 398, 455, 73, 85, 20211, 343, 1565, 2042, 14088, 69516, 1517, 82, 5697,\n      80, 2554, 88, 2005, 65736, 17043, 677, 19747, 28927, 69, 332, 70, 17207, 80,\n      74, 1729, 2249, 82, 911, 71, 983, 664, 80, 301, 450, 83, 2465, 3423, 307, 84,\n      4317, 80, 88, 275, 3172, 1800, 69, 352, 762, 36255, 953, 3696, 3919, 10470,\n      64087, 46640, 73, 2329, 81, 8050, 13009, 20191, 71, 73, 365, 23797, 14088, 78604,\n      3055, 8783, 85, 12953, 53060, 398, 79, 391, 22619, 540, 6043, 73, 85, 664, 77,\n      2235, 86, 344, 79, 708, 89, 406, 73, 360, 2933, 41287, 9092, 88, 2026, 344,\n      89, 56099, 2201, 1073, 359, 65, 35401, 86, 1897, 78989, 2130, 89, 43312, 67702,\n      3906, 86611, 89, 894, 17692, 85, 30407, 86, 18854, 74, 710, 65, 93000, 13536,\n      588, 764, 69722, 11949, 22650, 86, 501, 24244, 637, 418, 5298, 89, 450, 88593,\n      919, 10036, 4341, 8480, 4341, 9907, 418, 87, 86, 80, 16276, 5104, 18854, 11328,\n      14878, 80, 269, 5298, 84, 80, 68412, 89, 4777, 70114, 575, 67, 4355, 351, 32868,\n      1146, 4341, 1331, 70, 5298, 77, 1498, 87, 2302, 18577, 998, 87, 664, 85, 1347,\n      1729, 9700, 708, 11949, 73, 2302, 74, 89, 73, 906, 1220, 21620, 80, 69, 40078,\n      5972, 372, 16916, 1215, 93797, 22016, 78772, 5289, 65, 7369, 12328, 9092, 67,\n      2302, 70, 7387, 80, 81706, 444, 647, 3418, 80, 73, 1073, 28679, 77, 4223, 894,\n      2701, 70, 6511, 10200, 4511, 77, 333, 27455, 509, 3368, 74, 17008, 93000, 18571,\n      19747, 87, 85, 5972, 84, 70014, 24752, 876, 28927, 18287, 318, 27515, 14029,\n      80, 30407, 1394, 82, 441, 266, 76, 45854, 1498, 582, 77, 24752, 74, 17134, 66,\n      5981, 67, 1100, 2562, 325, 86, 295, 55655, 89, 1331, 85, 1302, 80, 1216, 32868,\n      324, 35940, 1331, 9907, 2562, 9081, 4336, 83256, 46341, 303, 85, 2332, 70, 55418,\n      1030, 370, 73, 3368, 5241, 263, 29238, 8998, 23866, 2641, 80, 764, 5289, 15306,\n      1662, 28679, 77827, 8303, 20824, 35401, 23361, 9907, 85, 354, 86, 48738, 6993,\n      80, 1026, 1146, 1910, 12498, 80, 8212, 12825, 65, 391, 22119, 87, 22873, 8088,\n      24244, 915, 81, 11927, 6511, 307, 509, 52926, 1546, 4239, 47689, 27093, 28927,\n      24037, 1546, 81, 4223, 1320, 5673, 283, 69, 418, 87, 71, 455, 85, 4080, 80,\n      16618, 302, 911, 75, 2203, 48380, 80, 998, 67466, 14029, 1302, 72, 318, 51788,\n      84, 1813, 89, 31764, 32204, 1302, 3601, 44970, 80, 22119, 71, 29684, 4942, 1094,\n      318, 31722, 15008, 427, 79, 3178, 25506, 84, 355, 9092, 81, 4991, 55427, 73,\n      7005, 7141, 49595, 3427, 87, 332, 86, 80, 831, 71, 9701, 76, 44183, 295, 277,\n      363, 64087, 327, 53016, 85, 392, 24672, 8892, 3223, 83, 361, 89573, 69, 1029,\n      82, 12940, 352, 6200, 73, 42848, 5469, 31695, 275, 64003, 581, 2739, 710, 360,\n      40078, 581, 21659, 29238, 29700, 74, 77827, 12591, 79, 309, 587, 728, 9326,\n      8934, 53835, 325, 3059, 450, 83, 80, 8783, 402, 79, 10616, 363, 80, 11949, 1631,\n      352, 383, 21206, 1546, 35531, 74, 42818, 1029, 43505, 1791, 6511, 70678, 4922,\n      564, 56749, 89, 11328, 404, 3306, 76, 89, 657, 462, 447, 79, 447, 87, 86611,\n      8088, 71, 10036, 675, 27093, 84, 49450, 6331, 80, 69, 89, 70, 10616, 352, 354,\n      324, 89, 18577, 1302, 337, 2303, 36722, 1517, 15930, 69, 8510, 18854, 67, 50798,\n      1804, 77, 24752, 18571, 15720, 675, 1546, 71, 4912, 346, 28990, 24752, 544,\n      36238, 87, 2034, 6583, 276, 69, 73, 88, 303, 69, 5701, 2642, 25947, 377, 511,\n      77, 9117, 89, 3306, 65, 60933, 73, 31268, 39342, 511, 5701, 84, 360, 29229,\n      72, 324, 12825, 4937, 65, 2580, 16618, 87, 71, 25013, 2642, 398, 19072, 50798,\n      10056, 86, 85, 10056, 6292, 72, 540, 83, 3906, 266, 13009, 634, 3172, 31881,\n      347, 8480, 46224, 4484, 8783, 2130, 74, 911, 9988, 67, 1331, 1910, 22016, 29238,\n      4239, 47689, 38844, 22650, 89, 544, 22619, 71, 4680, 44067, 822, 88, 85, 2438,\n      86, 3647, 4680, 39911, 11328, 27093, 69, 318, 318, 1994, 7141, 876, 7513, 21659,\n      2319, 2076, 11328, 2298, 4223, 784, 85, 89, 80, 11823, 418, 1065, 300, 55233,\n      441, 80, 74, 87, 24752, 44970, 67039, 89, 81, 73, 267, 23913, 1007, 9700, 65,\n      27093, 28927, 77827, 3576, 39172, 1146, 953, 75721, 86, 455, 87, 86, 18854,\n      80, 8318, 540, 5418, 327, 321, 21796, 24752, 1885, 7737, 324, 66, 566, 84, 1739,\n      1739, 22780, 16276, 84, 80, 285, 894, 86, 830, 42848, 418, 23913, 28073, 20811,\n      86, 344, 3647, 86, 406, 2332, 70, 8910, 1551, 2308, 339, 14088, 69, 7488, 72,\n      12583, 316, 15618, 65, 20926, 11032, 71, 12412, 50536, 44067, 13855, 728, 278,\n      876, 581, 23913, 2727, 44970, 447, 8480, 540, 7047, 5132, 4341, 333, 27093,\n      1320, 72801, 31721, 78930, 462, 309, 23576, 19639, 59270, 32962, 437, 648, 1247,\n      1919, 9902, 1568, 4484, 983, 24752, 87, 418, 540, 89, 80, 34175, 14878, 12940,\n      2201, 4748, 375, 65, 1919, 65023, 564, 43518, 1100, 89, 85, 10776, 8839, 72540,\n      12498, 4215, 713, 36726, 73, 87, 10616, 77, 10616, 45015, 359, 65, 5298, 343,\n      92216, 87, 85, 344, 86, 22650, 953, 23913, 70, 31764, 64305, 75, 876, 70, 31695,\n      318, 876, 85, 28679, 31268, 52971, 78498, 12940, 73873, 6194, 77, 3601, 84,\n      2249, 75, 1551, 88, 38977, 3696, 936, 80, 70, 20975, 5010, 9081, 80, 764, 12184,\n      333, 637, 18854, 87, 7521, 3919, 634, 78, 1540, 89, 1662, 83, 39911, 8088, 4317,\n      329, 70, 3527, 40924, 74, 894, 1065, 18577, 74, 2641, 80, 336, 83, 1662, 59524,\n      5104, 1517, 70, 2554, 4168, 85, 39911, 73, 796, 37406, 89, 11099, 31172, 80,\n      17134, 84, 2005, 71, 28774, 2034, 15809, 1216, 69, 26397, 1100, 588, 301, 4777,\n      831, 2985, 1029, 94908, 9081, 1609, 8050, 73873, 20926, 275, 9832, 64519, 86611,\n      2933, 73, 1394, 7387, 818, 70678, 89, 1739, 21486, 73, 540, 86, 2067, 3306,\n      16276, 7369, 43813, 4341, 641, 588, 35531, 74, 6358, 84, 427, 40078, 94346,\n      8207, 10169, 89, 31695, 13223, 333, 355, 9110, 81656, 399, 79, 7907, 4021, 33721,\n      8942, 52971, 1394, 80, 325, 85, 796, 14736, 637, 6098, 40101, 74, 383, 441,\n      80, 17008, 437, 85, 22619, 80, 398, 87, 80, 73, 88, 5544, 8892, 24244, 652,\n      89, 23048, 80, 6200, 65, 3841, 43189, 1029, 9991, 303, 1026, 81, 302, 69, 418,\n      87, 566, 784, 9902, 370, 76, 32589, 1302, 48380, 501, 2192, 80, 60013, 2034,\n      1065, 41922, 3251, 9490, 1320, 69, 451, 321, 1336, 361, 29700, 16400, 77, 8671,\n      5544, 657, 81, 73, 911, 2312, 454, 1347, 13855, 2562, 80, 1310, 68054, 2642,\n      4942, 8207, 86, 331, 67702, 6034, 92216, 14170, 58781, 1609, 19239, 74, 50798,\n      377, 1310, 89, 564, 8050, 1919, 2857, 6043, 39911, 77, 9117, 1347, 76, 751,\n      41129, 89, 8212, 68054, 35531, 70678, 2857, 80, 9902, 67800, 89, 406, 17851,\n      89, 3013, 72, 360, 24752, 9902, 4341, 88, 830, 4385, 72, 1094, 1108, 437, 7217,\n      70, 3933, 88, 80, 2580, 9509, 73, 29700, 641, 894, 5964, 89, 85, 894, 540, 8783,\n      9490, 67039, 363, 81, 6511, 83, 80, 20811, 392, 3315, 2303, 2642, 70, 3306,\n      2076, 76, 89, 30142, 38041, 4937, 11253, 73, 4086, 581, 8376, 982, 402, 2319,\n      20306, 23457, 89, 44490, 675, 383, 22619, 80, 70, 80, 69, 3415, 68, 8635, 31172,\n      86, 11032, 447, 67, 4835, 65, 26397, 1962, 65, 5469, 343, 1029, 66, 1677, 87,\n      318, 86, 85, 1072, 39152, 1302, 1336, 80, 12591, 321, 7521, 42488, 87, 1546,\n      17082, 17851, 418, 5972, 23361, 69, 38253, 66, 60013, 680, 73, 34485, 989, 18244,\n      87, 398, 5298, 327, 1072, 3145, 355, 3178, 1739, 532, 20926, 81964, 22619, 32478,\n      73, 30275, 392, 10616, 87, 73, 86, 89, 21206, 80, 943, 80, 49938, 3576, 8376,\n      7717, 10784, 1105, 5481, 1247, 494, 86746, 9996, 55767, 17704, 75406, 28990,\n      77, 62604, 5481, 13028, 710, 1273, 53835, 77, 39911, 6375, 15618, 919, 307,\n      773, 85, 24752, 87, 5104, 454, 89, 35531, 8934, 13855, 451, 71, 2642, 347, 3178,\n      261, 87, 371, 2727, 402, 67020, 8462, 1100, 85, 360, 376, 40924, 84, 20127,\n      28679, 26047, 39152, 23866, 10616, 44183, 28927, 32589, 5104, 69, 1146, 45015,\n      351, 13183, 708, 1247, 85, 1310, 98714, 2191, 69, 12407, 359, 544, 80, 74, 6870,\n      84, 89835, 70, 8890, 352, 74901, 4385, 80, 3306, 86, 347, 86, 18244, 98493,\n      3601, 316, 89, 501, 22650, 1273, 76, 24990, 511, 911, 77, 5544, 406, 32204,\n      10616, 70, 376, 4744, 85, 3576, 84, 392, 71, 3178, 81, 20127, 3893, 80, 70,\n      344, 87020, 303, 65, 66362, 41933, 45015, 71, 9110, 86, 383, 764, 75406, 2496,\n      23913, 283, 80, 50139, 80, 56414, 581, 1302, 24990, 80, 7521, 77, 8480, 391,\n      3315, 23866, 24752, 1347, 67665, 73, 18442, 85, 501, 74, 2641, 48836, 19260,\n      588, 1662, 77827, 9451, 86, 540, 2319, 31881, 73, 6634, 564, 7513, 511, 1073,\n      276, 79, 2933, 80, 89, 4171, 16276, 73, 3841, 89, 4937, 80, 7521, 566, 9794,\n      6194, 80, 73, 10776, 14694, 84, 710, 10470, 67, 1302, 360, 73, 27093, 9490,\n      1146, 36068, 9490, 76, 8671, 70, 60083, 333, 3055, 10333, 797, 12883, 73, 89,\n      3013, 87, 21557, 80, 18577, 70, 1609, 14088, 75, 1791, 283, 73, 519, 11032,\n      1336, 723, 51998, 20127, 53289, 88, 402, 677, 418, 588, 85, 325, 12498, 96518,\n      4239, 6358, 4680, 87, 6133, 73, 86, 8376, 774, 303, 1546, 21807, 8637, 4680,\n      450, 447, 20127, 86, 47154, 11089, 74, 11949, 5979, 316, 73, 4086, 28774, 70,\n      21796, 80, 77152, 3178, 9902, 7369, 83, 73, 2562, 26738, 86, 11160, 455, 93797,\n      8839, 1923, 85, 4381, 80, 5964, 347, 869, 85, 20926, 85, 1394, 343, 86, 29700,\n      6194, 21206, 267, 1031, 14736, 67, 906, 80, 49755, 20127, 604, 1347, 277, 24752,\n      74, 4239, 454, 80, 1498, 73, 9112, 35401, 1302, 73873, 8910, 2026, 4086, 87,\n      86, 4341, 36238, 73, 89, 337, 266, 894, 20975, 3013, 89, 80, 61057, 46640, 318,\n      1546, 32962, 822, 261, 952, 283, 88, 70828, 85, 7047, 93797, 5531, 1146, 1656,\n      89, 70, 89835, 2034, 641, 4341, 3423, 85, 1031, 10616, 70, 713, 66, 4744, 94356,\n      28400, 85, 6292, 80, 295, 7737, 81, 45015, 1073, 86, 455, 2319, 1609, 65, 2329,\n      552, 7513, 1791, 69, 73, 1216, 13423, 87, 70, 19456, 1336, 352, 13009, 89, 5010,\n      78930, 86, 13584, 604, 41196, 47154, 21659, 82969, 5893, 21796, 89, 80, 1494,\n      31019, 87, 19639, 87, 73, 16499, 73, 10470, 894, 2580, 20211, 454, 9117, 324,\n      80, 73, 2005, 337, 5308, 258, 76, 89, 3933, 8207, 80, 2445, 77, 80, 8318, 352,\n      80, 652, 11328, 35531, 80, 7369, 8671, 6194, 89, 275, 4168, 69, 89, 398, 343,\n      75, 4341, 752, 301, 94055, 10462, 46640, 267, 51622, 360, 96518, 22119, 73,\n      86, 677, 2329, 12940, 86, 12806, 7783, 49450, 18287, 74, 1631, 352, 86, 6194,\n      3340, 75, 10616, 302, 73, 376, 31172, 9832, 2642, 22016, 5289, 31172, 56266,\n      14170, 81, 1919, 87, 1026, 80, 2642, 267, 1494, 447, 85, 1813, 3601, 80, 8910,\n      76, 1072, 64, 37135, 391, 10776, 1073, 21301, 45228, 85, 16400, 74, 939, 70,\n      1100, 96518, 299, 80, 441, 5481, 94908, 18287, 939, 78, 15769, 79, 5308, 14878,\n      86, 8318, 23913, 398, 327, 5641, 501, 318, 28679, 17851, 2034, 5531, 564, 40078,\n      49755, 28679, 71, 1551, 87, 35478, 9902, 302, 21206, 5010, 75, 8658, 20824,\n      76, 8671, 332, 15720, 418, 7047, 79, 1273, 3972, 9700, 67702, 983, 7387, 86,\n      89, 81, 73, 36722, 73, 47689, 70, 713, 276, 81, 2465, 20990, 45015, 831, 2303,\n      764, 267, 511, 31695, 21888, 316, 11949, 494, 87, 25105, 82969, 4223, 352, 65,\n      2880, 9902, 87, 20824, 5308, 796, 96518, 10333, 71, 398, 86, 4355, 3524, 50798,\n      23913, 89, 699, 2329, 47342, 10196, 266, 67, 402, 40078, 2249, 34946, 17043,\n      80, 372, 66, 634, 7501, 41796, 87, 74, 64003, 53835, 70, 784, 49993, 3415, 327,\n      77, 10036, 441, 67665, 81, 273, 501, 86, 13536, 86, 4168, 14170, 45015, 24244,\n      2319, 21659, 1310, 88, 80, 4239, 70, 1331, 291, 89, 67039, 73, 51924, 14878,\n      2784, 42528, 7141, 76, 16017, 71, 12328, 81, 21486, 79, 1031, 392, 4484, 588,\n      58305, 901, 365, 329, 2249, 657, 1804, 447, 45015, 23866, 1729, 67, 4991, 1498,\n      13536, 3978, 2005, 1336, 339, 85, 43210, 98714, 343, 92791, 74, 677, 76, 15618,\n      876, 8462, 911, 14029, 9907, 70, 346, 3524, 89, 59064, 822, 40078, 2392, 25457,\n      402, 9700, 81, 2554, 14966, 86, 16400, 89, 11328, 69, 4171, 79, 22537, 8480,\n      18571, 44508, 5192, 710, 12812, 830, 501, 17704, 86, 12498, 2365, 19747, 1031,\n      77, 38844, 80, 4080, 88, 8783, 2319, 1310, 70, 73, 57071, 1551, 94375, 89, 28990,\n      89, 4175, 9081, 1056, 23866, 10784, 5192, 87, 4922, 64, 1658, 27093, 2034, 52877,\n      27515, 4086, 81, 40617, 83079, 45015, 70, 80, 19239, 8088, 4942, 2933, 9832,\n      359, 76, 19383, 9832, 86, 5192, 817, 73640, 45015, 38977, 324, 6713, 71, 1302,\n      677, 35989, 9832, 266, 92110, 14736, 14029, 8892, 73, 87, 71, 94908, 406, 49463,\n      33721, 300, 70, 52097, 302, 12841, 2249, 8088, 85, 10470, 40078, 71, 2642, 74,\n      67039, 13997, 648, 39911, 19555, 26738, 84, 580, 18854, 80, 82999, 333, 93000,\n      2661, 540, 85, 6151, 677, 5746, 19456, 73, 85, 4193, 14606, 75, 303, 94468,\n      85, 2676, 544, 81, 4922, 4239, 79, 450, 1029, 14694, 1273, 1494, 1072, 11823,\n      91311, 80, 4942, 675, 675, 10462, 29229, 18854, 65019, 85, 78498, 509, 383,\n      336, 41796, 20990, 373, 12825, 80, 1273, 76, 581, 267, 80, 47689, 5254, 87,\n      14485, 53060, 9700, 352, 94817, 1658, 710, 96518, 764, 80, 82999, 88, 321, 1065,\n      1072, 14029, 38844, 7521, 69, 50798, 16373, 73, 70, 9996, 77, 3368, 307, 5972,\n      351, 1003, 88, 936, 351, 372, 391, 34175, 303, 1273, 398, 75, 447, 21963, 63643,\n      5683, 4355, 1662, 23576, 93000, 34175, 89, 8510, 332, 74, 8462, 77, 351, 87,\n      1609, 87, 86, 1725, 65, 511, 8207, 7387, 509, 73, 31695, 85, 1031, 80, 93797,\n      89, 9832, 73, 26929, 13028, 23866, 25658, 87, 72231, 1073, 75, 13045, 579, 5308,\n      71, 73873, 22119, 77, 752, 78, 762, 68054, 365, 683, 27780, 31019, 1336, 67,\n      2332, 2739, 86, 859, 14878, 2076, 710, 9701, 5981, 2465, 87, 365, 9258, 277,\n      58152, 321, 404, 51622, 300, 14029, 40078, 5289, 1302, 69, 73, 7141, 41796,\n      1468, 7141, 677, 87, 2192, 318, 94023, 66, 664, 80, 604, 18854, 10630, 3716,\n      455, 540, 36851, 88, 1073, 65, 4239, 15809, 26804, 764, 1394, 4991, 80, 88,\n      73, 7864, 385, 82999, 268, 18287, 60933, 86, 1138, 67, 3746, 21297, 74, 456,\n      4835, 820, 19555, 80, 2203, 22016, 6733, 62355, 76, 1216, 5972, 11305, 675,\n      41796, 4239, 911, 332, 9832, 88, 347, 10497, 71, 4171, 1897, 2067, 49755, 20127,\n      33863, 17528, 1286, 21659, 3423, 9117, 1073, 14878, 81, 1320, 64, 1540, 1030,\n      327, 7513, 7387, 69, 89, 4378, 29684, 4937, 23361, 6091, 85, 3315, 31935, 6292,\n      1813, 19456, 79, 9117, 796, 26929, 86, 9081, 4341, 68, 1302, 2302, 6194, 48380,\n      86, 1568, 1919, 359, 337, 19747, 6200, 375, 65, 15618, 86, 564, 69, 1026, 73,\n      87, 8674, 773, 19639, 86, 455, 2739, 1273, 67, 402, 2439, 90625, 2438, 66565,\n      363, 579, 318, 47154, 2329, 372, 12825, 76, 1751, 76, 906, 34175, 69, 95233,\n      1216, 76, 2302, 1336, 72, 592, 9700, 73873, 441, 68991, 13536, 66565, 4575,\n      406, 89, 588, 80, 1073, 77, 3919, 93000, 5104, 1609, 3906, 87, 14694, 817, 33686,\n      7513, 325, 25105, 8311, 87, 25457, 5104, 73, 89, 53060, 894, 70, 16276, 604,\n      21659, 710, 2445, 69, 41460, 7910, 5104, 28679, 266, 38041, 6375, 26929, 71,\n      14029, 45015, 71, 50813, 773, 87, 321, 85, 89, 275, 54964, 73, 38361, 344, 6043,\n      4843, 939, 73, 16400, 1320, 23960, 73, 52926, 19654, 3251, 73, 9117, 25105,\n      80, 76166, 637, 76, 38359, 398, 21659, 55282, 81, 18565, 1631, 73, 354, 1302,\n      14606, 876, 44508, 9112, 74, 80, 73, 87, 80, 392, 31695, 291, 2067, 66, 8462,\n      17134, 84, 5308, 1031, 79, 540, 316, 831, 80, 38361, 29238, 3145, 73873, 31695,\n      581, 8747, 316, 339, 89, 784, 1100, 74, 75406, 1662, 81, 377, 81, 2174, 69,\n      647, 7453, 73, 85, 27455, 80, 385, 89, 398, 1142, 75, 2554, 3418, 98667, 53289,\n      73, 22619, 74, 8311, 1273, 54681, 1302, 2054, 10743, 74, 87, 70, 8998, 1394,\n      28679, 57208, 20990, 983, 69, 3315, 53478, 266, 66, 86427, 80, 332, 77, 24752,\n      65, 32345, 4151, 332, 87, 3306, 4681, 50798, 7501, 80, 13423, 28990, 74, 637,\n      73873, 365, 86, 2249, 89, 85, 412, 86, 1072, 84, 3524, 27455, 4511, 10910, 21796,\n      80, 33721, 588, 40429, 3576, 309, 74, 5289, 48872, 1494, 78498, 55506, 87, 35531,\n      5972, 46341, 12825, 21620, 6511, 80, 38306, 17378, 354, 80, 69, 73, 85, 8587,\n      80, 406, 747, 337, 51924, 85, 3423, 7047, 89, 27515, 1026, 85, 1029, 83, 641,\n      77, 5544, 45015, 437, 13652, 764, 447, 351, 1103, 6733, 540, 80, 377, 544, 540,\n      74, 70391, 10776, 87, 5308, 939, 87, 339, 3178, 1791, 1551, 80574, 1394, 75,\n      12407, 60435, 80, 677, 81, 15720, 50139, 3919, 78, 581, 80, 89, 73, 581, 19072,\n      80, 74, 80, 73, 32868, 69, 652, 376, 582, 354, 73, 361, 785, 21963, 87, 321,\n      713, 52926, 73, 18854, 83079, 1919, 501, 3251, 92216, 450, 4942, 74, 544, 4285,\n      1055, 392, 27515, 1546, 82, 2302, 354, 87, 80, 1910, 86, 10776, 87, 5230, 53835,\n      71, 31695, 337, 4912, 1517, 69858, 392, 3906, 71, 2329, 544, 620, 80, 47689,\n      5241, 80, 73, 86, 9112, 72, 454, 12825, 77468, 18571, 1273, 66, 71690, 15809,\n      344, 6331, 372, 28990, 2933, 88, 7783, 80, 25604, 86, 85, 8671, 1073, 9490,\n      1729, 88, 354, 17704, 73, 38041, 1031, 2143, 49712, 73, 634, 76, 36463, 652,\n      302, 83, 73, 87, 10616, 15618, 377, 88, 73, 17247, 283, 4484, 1029, 2005, 1910,\n      2034, 31268, 668, 73, 48372, 5010, 376, 74, 14878, 81, 26397, 86, 675, 8783,\n      2642, 70, 80, 343, 80, 4777, 295, 13584, 86, 5964, 7141, 71, 8458, 2303, 8212,\n      94908, 5308, 71, 13423, 85, 89, 3306, 848, 1072, 344, 67665, 2329, 87, 450,\n      2868, 1073, 74, 17156, 80, 4223, 89835, 89, 6634, 21046, 73, 14244, 6200, 89,\n      14694, 263, 79, 1031, 10776, 65019, 1551, 406, 76, 6358, 8088, 318, 71, 1804,\n      8883, 10910, 23001, 24012, 80, 73, 95398, 2034, 3906, 80, 12341, 14606, 87,\n      391, 73, 2329, 485, 75406, 24990, 46640, 64087, 754, 822, 80, 70, 376, 269,\n      87, 27515, 86, 5308, 50139, 1395, 402, 3013, 86, 1026, 16400, 67702, 1764, 4922,\n      19644, 65, 4341, 8587, 89835, 511, 91485, 80, 69, 73, 19456, 73, 8462, 728,\n      1094, 31268, 87, 71, 5981, 89, 80, 372, 9700, 26397, 73, 21620, 51622, 1026,\n      4223, 87, 4175, 2332, 76, 17912, 69, 10176, 80, 38359, 2727, 34175, 80, 9991,\n      6414, 19747, 333, 8255, 352, 418, 677, 60933, 346, 70391, 80, 9112, 351, 89,\n      540, 267, 49463, 1551, 2562, 4341, 3893, 501, 73, 1658, 13045, 285, 69, 754,\n      80, 5701, 71, 39911, 81, 73, 953, 83214, 8311, 73, 19555, 86, 9112, 392, 40078,\n      3251, 52971, 87, 28679, 67, 2438, 80, 285, 7521, 50798, 383, 22119, 604, 80,\n      7387, 339, 28927, 41817, 28990, 10516, 1658, 2302, 91650, 26618, 1729, 3013,\n      641, 4991, 73, 2312, 12940, 24620, 36068, 51622, 73, 6634, 29224, 372, 88, 11949,\n      295, 20211, 17134, 5298, 87, 437, 402, 1347, 939, 63643, 20926, 89, 7141, 80,\n      1273, 36825, 8783, 73, 4912, 5972, 85, 33863, 869, 303, 2042, 74, 1072, 455,\n      664, 1394, 19072, 8385, 86, 1631, 81, 35063, 73, 1609, 88, 10616, 67, 64087,\n      8480, 292, 41196, 31019, 316, 70, 939, 45015, 309, 89, 18577, 2554, 73, 1897,\n      41129, 333, 71, 3893, 18442, 24752, 29811, 65, 33863, 3696, 18571, 7129, 80,\n      2303, 668, 911, 87, 10056, 95233, 10910, 1320, 18577, 16276, 24752, 5298, 86,\n      89, 2042, 16731, 38359, 6870, 80, 20824, 1897, 80, 1347, 39911, 1517, 78498,\n      796, 73, 21340, 86, 46224, 278, 1029, 82, 3251, 23866, 67702, 3251, 4659, 30506,\n      1394, 398, 754, 80, 70, 1517, 82, 2933, 89, 43441, 5418, 67175, 1729, 28700,\n      63848, 316, 273, 9117, 2739, 73, 1029, 72801, 3633, 73, 85, 8671, 316, 17156,\n      12328, 12682, 4171, 42294, 5192, 73, 1216, 32204, 87, 70, 399, 21963, 89, 360,\n      14736, 16400, 1813, 21206, 74, 427, 1494, 5104, 346, 444, 84, 5241, 23866, 2067,\n      79, 10470, 11328, 74, 2465, 70, 73, 87, 2933, 88, 3696, 69, 9081, 17134, 1725,\n      8212, 1031, 19866, 77, 3576, 7908, 31803, 773, 43686, 1498, 1658, 17156, 511,\n      22619, 86, 7141, 2042, 77, 6194, 85, 6200, 1658, 5469, 2562, 84, 23361, 65,\n      5104, 450, 67, 1725, 73, 11089, 67039, 343, 5469, 49755, 25658, 2465, 10470,\n      73, 4838, 23866, 74, 66867, 911, 4341, 1658, 27106, 352, 41796, 91998, 16514,\n      1031, 65, 8536, 80, 969, 869, 38181, 12116, 87, 73, 1919, 359, 85, 5308, 75,\n      29700, 70, 80, 2026, 2302, 69, 10784, 89, 1725, 86, 4991, 79, 27515, 71, 7369,\n      69, 418, 62585, 65, 376, 77, 10910, 266, 8385, 575, 29700, 1517, 566, 11748,\n      85, 42818, 4484, 2580, 69, 1494, 8671, 65019, 9258, 316, 1791, 9081, 575, 87,\n      1026, 81, 620, 589, 80, 332, 7387, 24672, 73, 38361, 89, 70, 876, 89, 4239,\n      21888, 83448, 45775, 85, 455, 5241, 67, 796, 42908, 64123, 76, 1073, 79, 564,\n      18894, 2067, 1725, 65, 80, 24244, 375, 45015, 1331, 953, 13009, 89, 32962, 7501,\n      70678, 2329, 77, 39911, 73, 21807, 31881, 648, 57932, 70, 292, 77, 80, 2438,\n      29238, 10616, 22524, 285, 26397, 74, 80, 1302, 911, 1195, 86, 89, 4239, 79,\n      2319, 89, 2303, 37406, 27476, 73, 13536, 80, 2176, 1944, 441, 31141, 69, 1336,\n      15802, 73822, 21888, 1962, 91299, 32204, 376, 53060, 447, 5298, 85, 634, 359,\n      752, 7521, 3919, 87, 1910, 2445, 49450, 73, 27093, 7737, 2689, 8088, 22016,\n      86, 336, 16094, 73, 728, 18244, 87, 10056, 18287, 1302, 69, 587, 81, 73, 13075,\n      67665, 3427, 675, 80723, 80, 52926, 73, 1897, 20990, 301, 70, 3906, 80, 3696,\n      73, 566, 587, 8892, 80, 427, 29443, 70118, 69, 73, 87, 85, 637, 77, 3601, 37406,\n      86, 9188, 2933, 80, 73, 398, 1919, 65, 8587, 316, 3423, 85, 20191, 6194, 346,\n      1100, 12821, 450, 77, 455, 82969, 75406, 4080, 32280, 43776, 49755, 2580, 76,\n      299, 23770, 5701, 5241, 65, 1031, 85, 6511, 675, 24672, 77, 80, 1662, 8587,\n      1065, 4223, 566, 1030, 80, 2026, 82, 713, 24752, 455, 46246, 540, 365, 93797,\n      41101, 17043, 460, 71, 91849, 4991, 327, 73, 87, 1336, 2727, 10616, 18244, 31019,\n      316, 402, 42818, 7129, 587, 89, 31764, 7513, 3306, 21206, 383, 73, 85, 501,\n      80, 69, 3251, 1546, 51924, 80, 1100, 2042, 46051, 86, 49595, 89, 299, 321, 38639,\n      24752, 66, 1729, 939, 1302, 402, 76, 9490, 60933, 4843, 67, 447, 84, 455, 31268,\n      22016, 80, 269, 97523, 455, 491, 77, 31881, 3368, 9701, 915, 65, 939, 8050,\n      67, 3368, 81, 2727, 41129, 309, 944, 76, 876, 2026, 83, 33863, 2857, 2933, 71,\n      2852, 2005, 4168, 73, 87, 86, 34855, 18854, 427, 75, 1662, 41625, 1897, 3035,\n      43505, 3696, 70828, 73, 3415, 587, 77, 46390, 455, 50139, 23361, 70, 2034, 3180,\n      309, 66, 88183, 347, 1791, 1126, 4341, 73, 18442, 85, 89, 5192, 1336, 50226,\n      35531, 2465, 75, 5192, 372, 21963, 2642, 3251, 6870, 1551, 7501, 94055, 11328,\n      1897, 434, 69, 89, 73, 1551, 80, 936, 73, 346, 1065, 73, 89, 1100, 2642, 3675,\n      73, 1395, 352, 73, 4341, 45775, 347, 76, 728, 80, 906, 2319, 88, 327, 1764,\n      351, 1055, 283, 88, 89835, 2026, 85, 89, 59125, 876, 76, 12940, 6780, 53146,\n      71, 360, 65, 41670, 53289, 1751, 858, 15444, 339, 710, 87, 437, 89, 73, 11253,\n      2329, 76, 15809, 327, 80, 2026, 764, 2312, 4991, 18244, 4317, 581, 77, 1331,\n      65, 8910, 92216, 59448, 86, 3035, 73, 2857, 77, 3178, 664, 87, 46341, 70678,\n      3647, 85, 42908, 11032, 587, 79, 346, 1411, 6511, 67702, 4341, 80, 78, 336,\n      38361, 70678, 80, 7521, 80, 50139, 89, 27093, 604, 28990, 49461, 69, 3696, 69,\n      3059, 1609, 44528, 12407, 9700, 87, 953, 7947, 87, 8510, 6511, 73, 70404, 65,\n      2580, 80, 4086, 16115, 23866, 80, 1302, 29200, 73, 752, 87, 327, 86, 509, 86,\n      3933, 321, 89, 454, 2465, 2249, 4680, 86, 1320, 31764, 31695, 73, 14736, 7783,\n      87, 29684, 2562, 80, 70, 80, 10616, 7737, 377, 566, 329, 19285, 3906, 41922,\n      1498, 35531, 89, 16017, 6634, 4511, 2465, 19239, 82969, 8839, 77, 564, 69, 1031,\n      267, 73640, 87, 28679, 24990, 983, 1065, 7369, 89, 80, 344, 8462, 84, 648, 65,\n      3415, 285, 44490, 75406, 7488, 14736, 67, 337, 16276, 718, 29684, 89, 3316,\n      73, 4010, 36068, 4341, 25299, 708, 71, 4937, 69, 73, 22619, 2465, 876, 8587,\n      74, 49755, 80, 1725, 86, 7501, 1026, 80, 4341, 85, 1029, 6885, 266, 1551, 564,\n      87, 8510, 80, 8207, 2034, 2706, 50039, 41922, 80, 12591, 321, 63643, 85, 540,\n      86, 89, 598, 79, 5697, 762, 23866, 89, 355, 14029, 19456, 17063, 20372, 764,\n      31764, 73873, 27495, 648, 575, 81, 28927, 74, 2641, 8207, 89, 73, 56871, 1546,\n      392, 67, 5981, 80, 5298, 4239, 35531, 89, 81, 360, 86, 7911, 511, 8998, 44183,\n      266, 32204, 52719, 418, 86, 1725, 87, 39385, 73, 376, 9117, 347, 79, 1813, 869,\n      74, 939, 87, 9779, 657, 5308, 82, 1609, 80, 15720, 73, 3415, 1065, 20811, 906,\n      74, 87, 797, 69, 32589, 1302, 42051, 333, 27455, 1336, 13351, 73, 36825, 343,\n      6780, 80, 292, 31019, 267, 3601, 5289, 1631, 566, 87, 35401, 796, 70, 8910,\n      15809, 50798, 1517, 41796, 3178, 81, 8671, 5010, 2344, 86, 455, 30863, 318,\n      3059, 11823, 73, 8376, 62220, 94908, 26738, 86, 4835, 1517, 87, 53016, 17063,\n      85, 6200, 5981, 77, 14468, 1725, 10056, 8050, 94346, 2329, 73, 4175, 79, 24752,\n      87, 5981, 2201, 447, 2642, 86, 9218, 20582, 77, 10776, 50139, 5346, 79, 361,\n      1146, 1247, 29238, 1065, 26929, 97523, 89, 7369, 21620, 754, 68, 283, 50798,\n      4744, 86, 346, 31422, 88, 352, 26474, 359, 16276, 71, 1302, 648, 1216, 89, 13752,\n      604, 79, 911, 87, 84, 2826, 12825, 351, 876, 29443, 74, 6870, 80, 82969, 2154,\n      65, 3696, 587, 40213, 12328, 588, 10784, 85, 2411, 9907, 6358, 85, 19747, 332,\n      773, 80, 20553, 587, 76, 370, 547, 547, 4021, 79, 11032, 1725, 291, 77, 32204,\n      54964, 370, 73370, 39911, 2438, 15618, 44183, 4223, 87, 2249, 7453, 89, 953,\n      1347, 17704, 70, 7141, 88, 31278, 604, 67, 86682, 5721, 637, 27093, 50536, 911,\n      12328, 86746, 9810, 73, 88, 69, 894, 7737, 53016, 73, 51622, 40375, 66353, 710,\n      71, 4719, 1100, 24672, 32962, 21206, 61057, 764, 73, 50536, 2067, 5683, 47617,\n      18244, 71, 4080, 1029, 17319, 1494, 16618, 17156, 80, 333, 363, 56871, 12328,\n      75, 12591, 19239, 77, 19639, 89835, 5308, 5532, 73873, 31019, 361, 70, 32589,\n      375, 5481, 344, 27515, 71, 5794, 47875, 385, 25299, 68151, 566, 14046, 44183,\n      39911, 79, 391, 35478, 1347, 73, 3315, 21963, 74882, 89, 677, 1320, 351, 86,\n      41796, 89, 63502, 87, 94908, 983, 51622, 17008, 8088, 5981, 77, 2034, 75, 1030,\n      2701, 303, 70, 911, 17134, 89, 53835, 77, 1643, 64, 352, 83, 80, 74, 69057,\n      9991, 16400, 31764, 73, 22619, 6331, 80, 22016, 87, 906, 604, 26397, 3368, 68,\n      427, 3919, 73, 20824, 5192, 392, 80723, 88, 14736, 26474, 86, 85, 8212, 20191,\n      80, 318, 5701, 39911, 8910, 18664, 86, 708, 71, 5104, 953, 80, 18442, 347, 11089,\n      4341, 365, 6489, 80, 88, 9907, 2396, 70, 6358, 6331, 3172, 406, 4469, 3251,\n      5010, 57504, 65, 80, 1320, 76, 1310, 37541, 953, 71, 7369, 278, 7488, 45015,\n      798, 318, 15930, 29700, 57671, 343, 32962, 89, 23361, 45062, 391, 12940, 96295,\n      35203, 85, 1804, 23001, 50536, 2332, 65, 35401, 6200, 71, 652, 13752, 4010,\n      5701, 85, 80, 8207, 89, 4239, 89, 48380, 648, 28679, 6194, 43210, 29684, 2562,\n      74, 89, 7369, 4080, 41922, 80, 418, 70, 375, 65, 402, 76, 1007, 454, 74, 1065,\n      81, 2005, 71, 11823, 588, 80, 833, 24672, 331, 85, 1331, 9832, 81, 566, 652,\n      80, 5981, 1273, 71, 447, 4341, 70, 1494, 267, 83, 73, 32547, 710, 4912, 8512,\n      24620, 89, 9700, 6200, 302, 258, 18577, 14833, 501, 73, 1347, 18577, 1517, 17008,\n      587, 1336, 6194, 13545, 69, 332, 406, 89, 540, 911, 20824, 998, 2933, 30403,\n      68003, 62497, 797, 98418, 70014, 15618, 74, 14029, 89, 7521, 65, 7488, 5192,\n      85, 1072, 30863, 5469, 1146, 391, 454, 85, 2629, 80, 2176, 89, 27278, 509, 88,\n      30506, 84, 1739, 87, 788, 1517, 77, 2438, 4239, 9451, 648, 830, 86, 346, 587,\n      89, 332, 6438, 93000, 26397, 32589, 3516, 31695, 363, 85, 12328, 74, 3315, 337,\n      1609, 327, 876, 352, 613, 8826, 2642, 1739, 66, 44970, 73, 85, 22619, 85, 1331,\n      76, 634, 29700, 1031, 3576, 88, 6043, 80, 395, 5469, 69, 347, 87, 710, 80, 74,\n      70391, 467, 5241, 370, 637, 69, 339, 3524, 44490, 73, 441, 36107, 4484, 73,\n      70, 2642, 82999, 87, 6885, 1609, 17319, 86, 32478, 80, 64087, 7513, 4168, 9701,\n      351, 6375, 86, 21206, 5469, 355, 1031, 67, 4171, 7737, 4080, 9701, 1394, 2642,\n      2034, 8536, 324, 87, 32589, 42888, 15809, 351, 30506, 13136, 62327, 73, 983,\n      2042, 52097, 20898, 16618, 59524, 796, 376, 9996, 3013, 38984, 4171, 87, 86,\n      9991, 85, 89, 2249, 1286, 22119, 540, 2465, 14088, 20127, 89, 7369, 6511, 80,\n      42818, 28990, 65, 80, 566, 18571, 85, 588, 39911, 2005, 372, 97523, 38844, 20926,\n      80, 18894, 64087, 14736, 1494, 86, 1494, 7521, 65, 5104, 73, 70, 27093, 84,\n      564, 20926, 74, 6194, 385, 80, 3919, 764, 87, 80, 491, 53060, 830, 822, 45015,\n      89, 3306, 290, 37406, 675, 84, 7488, 71, 1331, 30407, 1310, 1026, 1026, 5469,\n      894, 3933, 88, 634, 87, 14736, 31881, 89, 73005, 363, 67, 4223, 3316, 75, 8510,\n      80, 18287, 911, 70, 582, 3178, 80897, 3418, 87, 2329, 86, 31019, 17008, 2026,\n      74, 14170, 3893, 86, 355, 11377, 4010, 5964, 74, 80, 89, 359, 1804, 44490, 73,\n      11949, 26205, 343, 89, 25299, 4086, 38041, 1725, 86, 377, 86, 332, 939, 339,\n      36068, 67039, 333, 2862, 6370, 13536, 3524, 263, 456, 18854, 65116, 74, 354,\n      4080, 33721, 86, 1764, 359, 6194, 269, 450, 66, 3055, 6672, 73, 3368, 18499,\n      85, 2857, 69, 73, 10630, 85, 564, 85, 1729, 5972, 80, 6634, 87183, 5308, 65,\n      19747, 74, 1394, 77, 2933, 23361, 953, 2933, 85, 17008, 300, 73, 354, 8207,\n      52360, 2303, 604, 10470, 73078, 1639, 17063, 89, 652, 18287, 391, 66, 564, 45015,\n      86746, 5469, 8503, 87, 8050, 70, 77827, 45015, 5469, 53289, 4922, 69, 4010,\n      404, 1729, 447, 675, 333, 13536, 292, 86459, 337, 1336, 89, 8480, 6511, 94908,\n      2249, 540, 876, 73, 784, 754, 1662, 69, 7488, 44970, 9197, 278, 1273, 73, 1910,\n      363, 9902, 95780, 14606, 80, 754, 69, 729, 7141, 5192, 21888, 283, 1289, 1662,\n      805, 66, 634, 6780, 352, 79, 1609, 69, 1498, 31019, 375, 4381, 89835, 12825,\n      73, 4744, 78930, 318, 13423, 24990, 370, 19639, 73, 55233, 1394, 3427, 41796,\n      69, 7387, 70, 52513, 2319, 87, 2445, 86, 347, 31695, 60013, 652, 3933, 80, 8892,\n      5289, 21807, 657, 54532, 81, 20553, 28679, 9991, 86, 8318, 2005, 82999, 604,\n      49712, 3368, 406, 7521, 16017, 728, 1331, 581, 7513, 73, 18894, 87, 75406, 80,\n      89, 85, 2642, 5746, 7141, 88, 44490, 339, 1494, 27515, 23361, 14773, 31881,\n      10916, 32962, 295, 9832, 89, 1517, 73, 85, 80, 25604, 21796, 321, 81, 8671,\n      894, 23361, 43505, 71, 73, 953, 41196, 2445, 318, 16618, 11805, 20127, 35940,\n      372, 80, 2303, 85, 2445, 77, 45015, 71, 2438, 80, 51622, 344, 87, 4223, 86,\n      16417, 34263, 80, 32204, 73, 88, 347, 48372, 3893, 39152, 399, 96518, 1072,\n      299, 3576, 69, 98347, 6100, 22016, 15618, 16915, 8462, 73873, 17134, 77, 406,\n      86, 96250, 344, 65, 764, 89, 21206, 7044, 78, 1662, 1727, 80, 30506, 43319,\n      830, 2365, 3919, 29238, 73, 7783, 88, 1551, 69, 1146, 383, 641, 3172, 87, 278,\n      5104, 258, 81, 73, 333, 6043, 73, 1631, 35531, 3315, 392, 9902, 80, 73, 27515,\n      9081, 3919, 316, 581, 2203, 74, 398, 370, 17063, 42050, 2580, 73, 5298, 652,\n      87, 71, 52097, 2465, 8890, 86, 4223, 8212, 97816, 1498, 346, 70, 73, 2580, 18854,\n      78604, 1310, 84, 1512, 25457, 89, 1026, 8462, 2329, 88, 2396, 68, 1263, 75,\n      3933, 75092, 8587, 3826, 80, 437, 4680, 81, 3933, 3988, 936, 10644, 70, 564,\n      36722, 572, 8910, 710, 12214, 31019, 87, 3655, 796, 65, 80, 73, 70, 73, 267,\n      344, 80, 3893, 327, 70, 31764, 1910, 36851, 2249, 604, 4991, 544, 70, 5298,\n      90173, 953, 9991, 88, 60933, 2067, 5972, 42908, 604, 87, 10776, 21659, 9334,\n      22619, 1394, 31268, 1310, 55895, 3576, 4991, 14122, 72, 801, 4239, 427, 50798,\n      796, 40078, 74, 2580, 88, 1910, 74, 343, 354, 80, 444, 16373, 89, 73, 11328,\n      28927, 73, 67910, 5230, 76, 10910, 22524, 44490, 99692, 3159, 14088, 5241, 80,\n      1100, 7737, 74901, 4942, 11851, 10470, 7737, 2203, 86, 85, 80, 73, 87, 80, 418,\n      85, 4922, 77, 10784, 818, 295, 35531, 89, 9700, 352, 87, 86, 292, 49755, 3601,\n      29238, 652, 604, 36851, 4680, 78, 343, 36825, 36068, 80, 1336, 1729, 83, 58631,\n      1302, 80, 295, 80, 73, 344, 69, 22016, 86, 657, 3368, 85, 25299, 53470, 454,\n      8910, 80, 402, 10776, 79, 1662, 2203, 3919, 65, 5972, 35531, 789, 48380, 16915,\n      69, 2329, 2329, 73, 2629, 12825, 713, 1030, 70391, 3646, 2470, 32547, 21878,\n      5697, 80, 89, 22524, 370, 12498, 953, 67, 1302, 3059, 953, 1029, 6455, 2580,\n      73, 2312, 21888, 80, 1320, 1517, 81, 713, 73, 8998, 8998, 22580, 89, 64145,\n      73, 418, 24752, 318, 83, 27455, 80, 70, 266, 77, 80, 3172, 3458, 797, 9810,\n      87, 2201, 2176, 2249, 1347, 87, 3251, 89, 6634, 71, 3423, 89, 80, 652, 95589,\n      9490, 332, 10470, 8480, 21796, 46640, 9902, 35278, 12116, 67, 5972, 76, 4625,\n      73, 63643, 1631, 509, 73, 36068, 41287, 2850, 20850, 581, 2203, 4777, 372, 80546,\n      19456, 544, 81, 544, 7488, 77, 773, 76, 44906, 352, 5192, 89, 31019, 9117, 894,\n      32589, 2347, 65, 1130, 58153, 370, 31268, 65, 418, 89, 16276, 1029, 68054, 2701,\n      69, 295, 85, 28990, 80, 65019, 365, 28679, 76, 7387, 85, 1739, 46483, 72, 414,\n      39911, 24990, 2826, 797, 4484, 60933, 86, 2042, 818, 392, 564, 73873, 48642,\n      3919, 31881, 29238, 352, 24672, 77, 3906, 4922, 65, 24752, 5972, 3418, 637,\n      35531, 42818, 4777, 327, 43505, 454, 70, 1804, 9996, 50798, 15720, 911, 1658,\n      70, 1302, 307, 3520, 876, 437, 5964, 86, 3696, 51924, 31695, 652, 13856, 300,\n      4168, 73, 2438, 80, 1494, 73, 89, 73, 462, 85407, 7369, 21206, 75, 11823, 437,\n      19555, 17063, 74, 2635, 31695, 74, 9832, 67, 321, 73, 818, 6043, 16944, 84001,\n      73, 5241, 49463, 89, 24738, 10630, 3601, 385, 28927, 80, 2933, 25105, 73, 939,\n      13752, 73, 86, 4484, 1804, 10470, 5683, 15479, 70391, 55334, 80, 69, 3858, 67,\n      427, 344, 309, 26397, 68054, 9092, 80, 56871, 20926, 93797, 70, 73, 87, 1149,\n      3172, 447, 14088, 2319, 69, 8510, 73640, 43505, 404, 3576, 38149, 509, 564,\n      325, 21796, 68054, 4223, 303, 15930, 385, 89, 42908, 1609, 65, 27093, 10616,\n      17156, 12825, 2642, 32589, 333, 363, 15720, 89, 80, 321, 85, 267, 89, 22580,\n      1517, 635, 1791, 52971, 7453, 19275, 483, 307, 1302, 64, 940, 74, 1201, 70,\n      754, 83079, 1919, 9700, 71, 2580, 302, 77, 3893, 4168, 32204, 74, 18442, 73,\n      6511, 418, 10188, 906, 2249, 69, 28679, 52926, 7488, 80, 18571, 89, 14694, 66,\n      6194, 7387, 86746, 4922, 83, 6410, 49755, 32893, 73, 3433, 64, 2176, 71, 34175,\n      85, 998, 80, 3647, 89, 85, 9832, 80, 261, 80, 38361, 4680, 2701, 86611, 1056,\n      72, 9490, 80, 3601, 89, 7513, 355, 383, 10616, 11032, 87, 1065, 76, 89649, 67800,\n      1247, 74, 87, 20211, 8619, 20811, 86, 830, 65, 81913, 80, 26397, 74, 7737, 333,\n      8088, 13028, 24037, 77827, 63502, 21486, 581, 5981, 3423, 55233, 321, 63643,\n      85, 89, 3601, 86, 89, 1216, 86, 5981, 33863, 2249, 5308, 23707, 5544, 38977,\n      723, 7141, 40924, 21206, 38844, 9110, 85, 581, 18854, 72455, 344, 9996, 72245,\n      2249, 87, 49463, 3524, 87, 3696, 80, 911, 2562, 83, 40016, 80, 7513, 1498, 87,\n      4937, 73, 70, 73, 10776, 4922, 1498, 23866, 50536, 20218, 587, 18287, 85, 302,\n      3322, 14694, 10033, 24468, 648, 65, 21620, 4341, 2312, 327, 73, 18894, 8910,\n      74, 7737, 3251, 831, 73, 85, 1739, 2933, 85, 2302, 664, 86, 89, 85, 406, 85,\n      339, 74, 9451, 76, 10776, 87, 80, 31695, 316, 10616, 81, 16400, 548, 69, 351,\n      72863, 31695, 80, 376, 17008, 2910, 587, 5893, 648, 269, 12828, 56871, 39911,\n      7387, 17553, 5289, 39911, 4341, 2249, 6489, 728, 4835, 74, 37955, 86, 536, 564,\n      45015, 65, 4086, 73, 10630, 325, 331, 301, 983, 74, 383, 71, 385, 2203, 77,\n      876, 911, 5972, 89, 13752, 24990, 70678, 708, 70494, 89, 4835, 42818, 5683,\n      73, 89, 652, 303, 4937, 86, 12825, 47689, 953, 88, 80, 64087, 4168, 25105, 89,\n      70, 652, 74, 728, 359, 61345, 5683, 74, 3545, 2026, 79936, 11513, 28546, 831,\n      1073, 20990, 85, 1394, 76, 21659, 372, 38844, 6200, 27093, 13855, 8998, 2203,\n      89, 451, 953, 13423, 45015, 23760, 58153, 911, 82, 98347, 7387, 73, 52926, 9907,\n      73, 88, 6703, 575, 4680, 88, 3841, 713, 437, 73, 59524, 1609, 43505, 6358, 93797,\n      1073, 276, 12940, 31764, 7513, 18571, 16276, 53191, 915, 88, 41129, 818, 343,\n      1910, 31268, 3601, 73, 1739, 80, 370, 303, 38181, 69, 447, 74, 1072, 575, 4484,\n      8311, 1026, 88, 5308, 675, 86, 28990, 641, 92216, 88, 80, 70, 25457, 73, 70,\n      5972, 9786, 80, 88, 509, 9991, 89, 5298, 450, 74, 1919, 372, 9092, 566, 939,\n      77, 10176, 52926, 80, 69, 34750, 398, 65, 80, 21963, 302, 67, 6723, 569, 86,\n      80897, 86, 12328, 73, 88, 80, 88, 85, 4937, 75, 375, 65116, 86, 316, 27780,\n      71, 73, 70, 73, 88, 7737, 307, 377, 14088, 53060, 9810, 87, 74, 50039, 36851,\n      86, 869, 42848, 23866, 77, 80, 337, 32962, 69, 6194, 17063, 67702, 329, 5964,\n      911, 86746, 74, 5964, 40637, 80, 1347, 501, 47154, 331, 85, 14029, 8088, 85,\n      3852, 634, 560, 39851, 1662, 14878, 40078, 764, 63913, 10784, 65, 7783, 404,\n      2034, 35478, 391, 44508, 3696, 86, 3059, 85, 31695, 2067, 55911, 18244, 35531,\n      80, 295, 3906, 7453, 269, 10910, 86, 16400, 38844, 869, 23361, 10056, 92216,\n      18244, 2411, 544, 2857, 93797, 86, 316, 86, 383, 18287, 1026, 822, 32204, 87,\n      818, 80, 7387, 575, 8892, 81, 5697, 1759, 65, 7737, 66, 3251, 12498, 437, 73,\n      2302, 303, 88, 32478, 86, 80, 47689, 10056, 7521, 69, 344, 96518, 509, 796,\n      87, 73, 89, 70, 73, 70, 19239, 344, 53289, 4657, 80, 634, 77, 6802, 582, 67139,\n      728, 89, 59367, 3893, 27455, 70678, 501, 14606, 80, 15618, 360, 8088, 18442,\n      455, 21888, 58305, 347, 89, 347, 74, 7047, 72, 292, 906, 78, 581, 14088, 360,\n      375, 73, 27476, 20127, 764, 71, 28679, 936, 80, 89, 36825, 80, 88, 1729, 983,\n      1065, 37406, 97523, 4680, 1897, 1347, 87, 89835, 31881, 70, 355, 55233, 22650,\n      7349, 9081, 267, 18854, 40952, 337, 14736, 5964, 74, 60933, 375, 40924, 10616,\n      70, 3841, 337, 73, 85, 33367, 31764, 677, 80, 44183, 372, 71, 22873, 637, 88,\n      80, 7488, 66, 2249, 70, 509, 94055, 19639, 81, 713, 21486, 85, 4777, 93797,\n      1273, 18287, 80, 73, 2438, 38359, 3858, 9991, 9081, 89687, 85, 20824, 87, 41622,\n      22016, 392, 797, 17008, 18571, 27515, 73, 82553, 86, 621, 19260, 1146, 89, 29684,\n      324, 71, 48233, 80, 2067, 28546, 8998, 68467, 540, 6358, 73, 86, 2067, 87, 14878,\n      784, 1791, 11032, 56871, 318, 1551, 4991, 63345, 796, 26397, 1100, 77, 324,\n      89, 4922, 76, 754, 80, 12591, 533, 2026, 84, 1498, 1804, 73, 86, 418, 654, 74,\n      8212, 675, 6200, 1320, 73, 392, 3251, 6375, 1756, 88, 351, 67, 22650, 73, 454,\n      69, 634, 87, 6511, 34175, 80, 3172, 9112, 85, 15464, 799, 68, 21963, 38359,\n      23797, 74, 6489, 70678, 19456, 71, 42818, 89, 553, 22119, 66867, 5469, 1764,\n      31697, 953, 75, 462, 25105, 488, 65, 27322, 73, 67702, 25299, 80, 4010, 92216,\n      4010, 74, 1910, 9907, 3172, 42528, 352, 302, 273, 75, 302, 68, 2113, 39911,\n      76, 1625, 17851, 80, 4625, 32752, 784, 80, 637, 88, 1336, 6091, 40078, 80, 52926,\n      25457, 418, 70, 4777, 92562, 11328, 11949, 46390, 10056, 74, 380, 73, 89, 641,\n      87, 71, 728, 266, 5972, 1302, 70, 19747, 67, 796, 327, 70, 1100, 4748, 266,\n      34175, 450, 361, 85, 8480, 32204, 69, 604, 1791, 447, 544, 85, 267, 437, 52971,\n      876, 76, 12821, 647, 80, 61828, 2580, 894, 87, 40078, 8480, 325, 14736, 63502,\n      46640, 544, 1331, 3172, 85260, 894, 69, 1302, 89, 728, 86, 85, 1073, 377, 8671,\n      19456, 80, 784, 87, 84, 77827, 713, 94869, 8998, 11949, 1729, 637, 21620, 84712,\n      66, 7387, 6043, 84, 329, 89, 309, 2201, 1498, 55233, 2332, 5192, 89, 38977,\n      566, 27515, 80, 69, 677, 25105, 762, 73, 70, 74, 677, 1247, 71, 25457, 80, 78,\n      300, 1725, 45228, 85, 6511, 74, 637, 45015, 2465, 983, 64087, 1302, 713, 11377,\n      40924, 89, 46341, 983, 85, 41129, 1791, 7141, 41796, 969, 14898, 73, 10056,\n      86, 511, 14736, 70678, 4086, 604, 71, 302, 78, 1662, 65, 5010, 79, 540, 2465,\n      7910, 333, 87, 4010, 86, 5683, 85, 406, 876, 20990, 11328, 73, 637, 81, 418,\n      295, 295, 86, 45015, 28774, 8892, 80, 9700, 53835, 25457, 13423, 42908, 77576,\n      797, 85, 657, 9701, 96819, 2438, 70, 59194, 73, 441, 52971, 17134, 86, 40153,\n      1494, 10056, 87, 73, 4937, 86, 375, 1804, 75, 90377, 73, 57504, 1791, 1897,\n      23866, 273, 3036, 292, 402, 21963, 983, 38977, 295, 4080, 80, 29224, 89, 752,\n      74, 80, 830, 8783, 2933, 45015, 7369, 77827, 1395, 73, 1394, 1394, 67, 5010,\n      77, 10910, 2933, 15618, 19456, 32962, 85, 5972, 88, 40078, 8890, 80, 12654,\n      12498, 80, 3306, 258, 71027, 13066, 85, 50798, 80, 939, 2302, 22374, 19239,\n      1302, 87, 73, 3418, 4010, 89, 501, 92180, 73, 63643, 321, 93213, 84, 21659,\n      303, 81, 73, 2438, 83227, 86, 8998, 65, 458, 1302, 14736, 45015, 20926, 5964,\n      32204, 784, 25013, 80, 4239, 81, 747, 21659, 652, 604, 30506, 7387, 710, 9490,\n      1494, 89, 1336, 73, 2933, 88, 15278, 2580, 1100, 275, 8658, 70, 74, 1739, 437,\n      27752, 87, 73, 41139, 74, 5759, 7369, 3935, 12328, 17270, 354, 85, 14720, 292,\n      9117, 31268, 2192, 88, 45854, 376, 764, 6511, 1030, 24470, 51622, 6358, 23866,\n      10616, 3919, 70, 5010, 67800, 980, 21888, 581, 77, 4239, 375, 295, 852, 74,\n      13183, 80, 11160, 77, 2312, 89, 3423, 65, 3427, 7453, 80, 74, 20176, 8747, 28679,\n      80, 1625, 71, 1146, 6539, 78, 648, 79, 1331, 85, 16400, 69, 11949, 80, 11251,\n      6043, 797, 652, 11032, 78930, 332, 74, 89, 392, 59524, 85, 267, 80, 3368, 24041,\n      83470, 796, 41922, 292, 86, 2668, 82, 9902, 689, 1900, 80546, 19555, 77, 39911,\n      81, 9786, 2319, 89, 745, 5701, 78, 336, 9907, 70, 3601, 88, 85, 5298, 80, 9672,\n      13846, 70, 329, 49755, 375, 85, 3013, 31881, 11377, 82999, 637, 4341, 398, 88,\n      88548, 16400, 11377, 39152, 80, 1631, 45015, 6358, 85, 8998, 58305, 652, 78930,\n      69, 73, 830, 70, 74, 3368, 657, 9490, 89, 752, 69, 26235, 86, 652, 3306, 72801,\n      73, 2312, 5544, 69, 752, 20211, 392, 50397, 3601, 773, 3368, 43389, 1394, 1910,\n      544, 8910, 81, 64087, 331, 85, 23361, 277, 2303, 332, 80, 73640, 2465, 1919,\n      67039, 74083, 604, 1791, 13536, 74, 14088, 587, 1195, 269, 1751, 42528, 80,\n      35401, 89, 3368, 94908, 728, 85, 89, 46224, 447, 87, 18442, 4341, 78604, 4922,\n      12825, 331, 283, 309, 85, 12184, 2303, 14088, 406, 634, 346, 88, 31764, 26397,\n      3368, 60013, 713, 70, 1739, 87, 587, 1029, 2933, 78, 42930, 2003, 86, 48380,\n      71, 17008, 5683, 24470, 8998, 74, 80, 344, 5010, 93000, 501, 40762, 4922, 66565,\n      80, 344, 76, 575, 2042, 76, 1026, 509, 73, 1804, 939, 7047, 5010, 92238, 292,\n      73, 354, 84, 70391, 5972, 88, 846, 2465, 37406, 89, 14088, 100120, 14878, 20990,\n      564, 31147, 983, 69, 664, 31019, 11823, 3418, 14170, 392, 49595, 7453, 40078,\n      8998, 36851, 80, 38359, 20553, 67039, 1662, 14878, 80, 44067, 2423, 316, 80,\n      13634, 24672, 66, 1029, 79, 3696, 24990, 80, 300, 17008, 80, 70, 901, 764, 1336,\n      76, 20926, 74, 11089, 23361, 14029, 454, 1029, 637, 18571, 85, 9081, 87, 86611,\n      509, 953, 80, 36825, 80, 354, 89, 7387, 44490, 4239, 7521, 77, 1910, 9907, 654,\n      42050, 1029, 52000, 65, 1791, 73, 301, 70, 581, 88, 73, 1517, 8480, 73, 635,\n      346, 20990, 24244, 85, 80, 74, 89, 16276, 93797, 86, 953, 87, 92241, 677, 85,\n      36851, 998, 2580, 7488, 87, 44508, 5490, 14029, 85, 26738, 10033, 84, 7387,\n      76, 2562, 66565, 728, 75, 30728, 5964, 74, 4239, 78, 292, 80, 88, 80, 4942,\n      24672, 19239, 1146, 1394, 75406, 73, 89, 1302, 77, 5104, 9864, 87, 354, 53450,\n      80, 73, 1247, 7047, 70, 2034, 77, 70391, 78498, 370, 6634, 20920, 9117, 79,\n      10470, 5118, 9490, 392, 63643, 89, 540, 67, 4355, 80, 634, 85, 23361, 92715,\n      2580, 85393, 80, 70, 32752, 46640, 2554, 2826, 4171, 4239, 12940, 2034, 88,\n      9112, 88, 18126, 1091, 78, 1100, 377, 93797, 13045, 365, 23361, 71, 35035, 32547,\n      13092, 85514, 1494, 73, 2727, 85, 14485, 87, 74, 1031, 7717, 80, 10333, 70,\n      80, 23001, 74, 398, 87, 1302, 64123, 86, 2034, 5308, 85, 42818, 303, 5923, 88,\n      5964, 7387, 13009, 51924, 87, 710, 69057, 325, 24752, 44508, 16510, 4937, 35531,\n      9832, 36825, 1336, 339, 69, 66945, 73, 1247, 86746, 89, 5192, 71, 25299, 455,\n      77, 455, 3315, 402, 1751, 14606, 819, 9117, 731, 30407, 28679, 2739, 2130, 331,\n      4719, 92238, 79, 2249, 1804, 75, 2329, 575, 6043, 84, 327, 75384, 5104, 299,\n      5717, 81, 466, 4752, 86, 89, 80, 1302, 652, 65, 4922, 544, 7141, 87, 46790,\n      321, 32868, 69, 6511, 88, 911, 466, 75406, 3524, 444, 2933, 71, 29652, 20990,\n      69, 7369, 17134, 69, 451, 372, 318, 953, 87, 501, 1302, 1804, 76, 365, 5972,\n      2249, 28679, 80, 14088, 1029, 28990, 372, 100111, 6634, 63813, 2329, 2329, 331,\n      27520, 80, 347, 8462, 46341, 44490, 575, 5010, 24470, 75, 3415, 3524, 454, 4381,\n      566, 713, 4458, 64, 2319, 74, 3919, 86, 1026, 75, 11823, 89, 634, 14088, 69,\n      1247, 88, 292, 321, 302, 80, 3988, 6634, 73, 41196, 2191, 88, 69, 7387, 1739,\n      74, 27455, 4010, 84, 2249, 76, 2026, 85514, 752, 17008, 86, 329, 4484, 278,\n      3172, 25100, 43505, 867, 81, 939, 27515, 64381, 70, 80, 22016, 86, 10776, 89,\n      4908, 89, 70, 14092, 830, 25457, 427, 754, 75406, 20218, 1073, 5230, 85, 377,\n      74, 4080, 1233, 19639, 12498, 39911, 2629, 12158, 13536, 582, 14170, 884, 85,\n      38844, 79224, 4168, 87, 71, 2249, 73, 70, 80, 70, 19072, 953, 56029, 2641, 69,\n      73, 2465, 36851, 73, 3059, 17008, 20824, 911, 80, 69417, 18442, 87, 51071, 360,\n      89, 8480, 268, 75, 3906, 89835, 1073, 75, 9117, 1919, 88, 360, 96518, 8462,\n      28679, 29700, 70, 1302, 65, 7488, 4239, 65116, 74, 21088, 2465, 10784, 85, 936,\n      38359, 3647, 27278, 89, 8480, 8480, 3906, 1631, 1494, 295, 80, 318, 1631, 268,\n      8050, 89, 3919, 61057, 77827, 39911, 354, 416, 337, 89, 9700, 69605, 6200, 1919,\n      69, 7513, 73, 26738]], \"model\": \"text-embedding-ada-002\", \"encoding_format\":\n      \"base64\"}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '44957'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/embeddings\n  response:\n    body:\n      string: !!binary |\n        H4sIAAAAAAAAA1SaWxOyOp/l799PsWvfOm+JICTsO04CAiYoiDg1NQWICKjIIQmkq7/7lD5dPdU3\n        XhDkEJL/+q2V/Me//vrr7y5vymL6+5+//n7W4/T3//oeu2VT9vc/f/3vf/31119//cfv93+cWb7y\n        8nar39Xv9F9j/b6V89///CX895H/f9I/f/0NxKClxgp4EdfwvQYlDBwa3usln99ibsHPRthT/bmU\n        YN7QvQGd6pBRa3NdIgZyzYUZLJ9km2bU5HVlJbCPzgNaz+LczCxxQ7g84QabxFUHhmxYKtWq3mAH\n        vdbDcgHvlUw3jkPUdbpv5tVkMxjHpYrY0DYmF2ZuwLN8V4gUaC6fywe31WovjtSYmevTdR8sYJ34\n        EhJvzSun5/wUACO2a3pAVgqoEB8ruFRuhZEvSjkRVg9PlTQkIm7Gg0k3uHhBefPpSRs6SzQbpSfA\n        I2sDjOqK8slscwM0couwi0DKR/uVBsol2RLymo5mxI/uo4ftVTZwUEq7Zk7EPYFed68Qh1o8zO1m\n        pcDkNQ/Ub7rHwPlQi2COj5Qe/N3DXDbWnMK3xxhZT7eQTzu4bmGFrgv1QnLzZ80+JwAb9IEkYsjD\n        +EgHF949uKV3sbF9njz6FFqHUsDG9dNHizhVBqhGuODdDTyaKciPNWwXqSRsPVScry7bFG5hmhG0\n        imROW0kW4PAWTWpJeBsxrLAACg25USw2L3/UkF3BLGkOSAblNMxhsl1gYxcuDXdP0iwPnEIgP6yW\n        KHIY5LyCWQvabWHgkzm+cuYLvgiIdgSo92Gez80tiyG9nq/U+LZ3xHcVcE/ICwmb6ymaZbEt4Il+\n        GAGOa5qb4xEI8H33dtQ3/XXOr/6YwCx5HMhqPRlc0BCqFdGvR3wQT3E015+yhkqt5jjzg35Ypqtr\n        gO/7o1ezTD5zV5CBWHM6jM+9zYdhPZdw38wXethusMnNXBPUwNwZBLR6PdDTHJ7Uz21XIqZtM3Na\n        baMtXHa9Tk1tZs3YOLWmHmOxRKoLnGihWR4qyWGDqXW5PCLSypkIk3t+Qo9nooONddgTaI/LHQfA\n        DCPWP0QN2qukxm6TeLnkf9IOAFfhGC1oBGz3dkKo+6aJd0YrNNN8NGO4xOmC/SI9DVIzfzrFyayQ\n        FsbF8QneTiGkZhDiK3K0YTPEqQgk543QwqIajLphxNBiL0B3I94MU5ajEbLSrLF3OUoDu6iLslZx\n        aFCjeu74om+ZBe/EXmHUHKyIPcVOBNsz5kQRp3noay/WYPDoDHqLw6aZKx5mQFAVh2pv38iJrKU9\n        DKTZpwcVtPlybswUon15xL/xvbBFEuDNen/IahcVnLtJZ8FojiXsxLszZ8nZOsF3Ne6pfu5avsSd\n        m0Cujw0OtMfDX86X1UnRr7OAz+en6vPbKSSQt8IH38aLHkn6uIdwRt6TLGDI/T6DgQvy/JAQOrIi\n        Z49mGwJNvmkYb5fJnCRWnGQNnk7f+rHlvLpCF5wlYpPv980XVjUlrObExbuNfvGXQ8xf6uFpQWxT\n        Zx9x/xP2ilxQhP1qjnJWRy8EJ8cYqNW4WTPn5iZTXSfTkXi/BjmPxjwG4bua6K65RZzMq2AF58dp\n        ROK3vizdZ4QwiIcdEdO9mi9AH7ZA259VtLg7J2dinDNwmEhDzQM8cQZqJ4VetM2wdo6Gpr/qexfG\n        2q4jomhagGb2O4X4Kb2xIa0Rn0kOTxCXN0QGLXjzwU06G+7y3ZXMN02N2GXv2nDINjZaeif1Z7ON\n        NPklo4lqVDX5nGOvAmrS59iyFtGfbqt9/NMDqtGQ5ktuxJnylHc9DrbVGXBNNS2IwMWl1oWvIuZ3\n        KwJi0r0RgG4V9Zr8dmEY7VPqkc5q5nJyEVz5cYudKwB8iQSrhnmpdfQ2y9HAz3mGIPDJDlvbj95Q\n        r9EK1Vt3Di0E4dOwqxclMBBUGTvf+kme60GDcXMgFJ12q4guhoDgvagARYCtzYGJOQP10xGpE40x\n        4JFUFQBW1EQ0D2ST3W6+Ap5YzChiqQ0Wd9O3YIutDzoGYhNNVD4vECH9Qm1/3ZgzvlBREedyh3VV\n        LpoZFeMCt5xxJBkbO5ql08Lgu0g41fPS47woYwXowLXp/Xh8+XPSw1bJmtojnciihpdpp8A+8VS8\n        t0s28DFNLKiGgk2A/NwNrDiKDF5UXcKHZ/4ESzGYBgx225gGxuXtcymHK/jpNgHeB9Nl4MeX6cKm\n        03zq3W51PqVG7cKxUZ5EKUw5GlvproCWnC54D8qpedpQq2CumyMODmMTMflMDSjebIoNmGLAkXso\n        gEcsi0bb2I3YQwx6SGTjiXW+2ud8pO8UFH58JavEMHy2Yb0G1VLjeC/tAi6A2slgnuOEMF028q8+\n        Zkp6ZjWqv/N3roWhB9uwm7B/3Ujggy9vAYSyzdCczEnEzHnvwmCnxIQvu0dErhsOYYXyBbF0feEs\n        nk8VRCs3o442jA2/7AoXBBL38d7zIB9CyTpBB2+f2HuIjcnOSLDBfnPOsB8p1jD3Bq9grF5TtJ3f\n        hs/bx72FG8pW1E0zbDLIxxEkdiHR/ePx4cuhWi+/90Hr7S5tPryuOrW4HLfY63HDGchdD37rCz6s\n        ho3/dK69BQ0FD2hzfqomLQ/RAimrdaIuL9df6vemht7RcWnA8g7Mct+FIOu3NUZ5G0dUiK8V7PZd\n        i111xOZXP05gXgSKjT045PM7lVuQ8KXDZqav+eQY4QKyimypkXPLZGD76OAUbDTsbdrKpGonV8AX\n        kiO2hFDj8+v0yKCiuAa136UcsewNRcCzfoWtx3pvSh/5c4Ju4i5YqzoHLLc5CoD2VlR8GC96TlTW\n        E2g1zxU1zuFnYPo16uFNb1/YPfmdP/RCm8AsogBtQ53k86m5eqDYVRY9njsL8Cm4bqEjPRfy+FBj\n        WC5t2UOopZheSeRH8zArsUp8ImAcCdXAb+1kAQbbGttz35pUH/UV7EvW0sCp0oYvz6yH/bwd8KHe\n        +v4871YB+F6fGuK+49OubxCUBGWNDao8wDKJnwq2JLzgwBTGfL4XKw9cDzeC5Pup5kzcow5szweO\n        jds5adh8kws4JqAjauQRn43WlsAtzDLs+G+Hz7I+d/CQxD49ZPZnWPZgYXDgc40eswNMNvA8BuMp\n        rhGorJKPWNkG4KeXwvngNCzbJSlUpv2O5FsfNvMpEBVYetKGtCs/4ptGASKMKONk4/cfwF5zs4XA\n        3j3oXu7eAxdUzYPJmGL6qxfjtx5DF9oedY57JSff+QeLjbAl8rifB65Xggg/oCvpIZLqgYnVBcKb\n        9fxgqwPtwEXv0kOzjwlS/Z1uzvNODIASiEeiNJEbsebpV6Au/AzJxg6DpcnlBMof4qNJKEhEb2CV\n        gqm8mmQTFkMz8Q9VlN7JAupImybinwZr8FAfe4xKwRwmEr69P/NXw1b7490Ksly7Y+N+Z9HkSP7r\n        xyN4HyfO8DSvOwV2z/REfYVIPk3DxwlSE4XYWSgyGftsethPzZmEoeJxvtJLD7DZ/2BbNFv+uqvg\n        BTDTT1i/abdo2Spaqh4/eYu4dSvAfK3MHtzelBL5BMtouZZ999M7JH/rAXPMmYEfr+0df2eyUNdK\n        2Kz8GE3lvY+4vCYd0M1uoNdKOOdLvbYFqKeGRg2s18N8vl5O8Muj1NkiKxfWgqtA28096triAL79\n        YygT7k40+/IcvQExA9trGJOxuqYmCT2jg63vHgkQ7ixfulu1wK8fItBSdCCqDrSh4ThPon75SXhB\n        WYMd5RM+fPFgZB+1A+o4t2iwnt0wfvkV4HyA1N4kLF/WhmarEagfX15so/lguQFUg5IheNq1/myy\n        OwJfvsTXve7n8+HxIUC7ugFFWV4DLqiuB61p7qh5F/bNsDxPHZzdOKSJZdwHtrqUpXJPxhcSZm1u\n        WLgBIQgOpxHrRr8d+EhYDFftUcOWdj3n7IMfHZDJ8Ui16PbMudsJJfjxm2/npKHrEyggF7ORHqz6\n        1Tye5fSC72gKECuXxzAfb+4KmikbkDyKL392F7uHws6/EQl5RsOFGRgwtNI39eXns+FW4iuwSp83\n        rF1E219W12OmLpfAwt9617Bj+YHQPmcOWrp+4VxN3wXc3/oD2tytyJ9/fk0/I4KY+/D8Ga39ACKR\n        Gdi567O/6NutDXVfN6ejX2QmP+cnpCaZENCyrvCX54QQzm4S4oN+uuTTXXBK6DTGSDVfOEdsc00J\n        XJ2IinFmOoMwkiQF8MLe9GAWs8l3R3sF7+tBxwY9HCIqe1yE7Ik8aqnlOmeiqCDIa/2Cd5qumNMH\n        rUe4Hpac7vZVaL4XpMcq0sSerI4fPVpgIGugUA8hNsbkbs5nKtcgNhQFbWNSg2XOSf3zY2hR6k/D\n        T3N6AmcYBUiZ30XOF7RPYF3CkdpB2prLfe+yP/0P8pPq83lOBOV40gN6sNNg4LdTOgJXDrc0pCGO\n        Xn7UxVC03Jhq/MNMeu83ITTb+op4dfAa1u2vBeQXaSTSUw0axiPpBX0yjXjf3Xa5oJVhCyq6WFTL\n        rhXo7XYXwq+e0EOX3Yaff4B+vSDqqiM1WSvdt3/88VWNOZ/pe58CPJQ+NtdhM/CXfLDB7J+jb76A\n        AbspUwYG+zaTuWi1fKnfagVUUcVIud3qiNZVEMPc7sLv96WA66grwW2lJNjqZ28gfJuuoF8zRO0W\n        rMA0WmiBUbF+/OGj/hRm4h/+0qBTmkuVnz34Xk7B16988i+P23Cy8JXqTSOB+QVCQz1SzaVaqPSg\n        j/zbFvZrJ0XCaaUNwpf3gCZ+CJm7szwwmJgICtrrQvdriURdAwsBipYX0y/vDmPvtSMcxuseGyyq\n        +bKpMwVc9vJM9aKtoiWmTgvqt+xiFHZXczEVM1GrMtC/eYneSJqbnsCFRDZ60rvVCEWtiao4bCrq\n        vk5PwBaQQfDVD4zfq6whVX5zIcPhTLYFx4CZGVEU8X3KsO28jIitpi2B3/wIB5/7lC9b3SGgV+oT\n        9S+vELBLHhfQkd4LtXXT4VKyNrdwoEFOVnxYTMaCwlVKiByK5bs+LDfYxZA8ugORpeWR8+EWaZCE\n        lkezk/syB6/RSgh8WcT7tYTyZffxArhv+AWxt1/nnGy0Wt3lzvXr597R0uunGiT364n6lVUCHqus\n        U1GuxfiP3iZnK4Rp20RE0K6bnI5kG4MbmqPf+PYZtc0VKM96hY23W0X8+PJdyOyPh9/PcOt3Ryft\n        oCHkCdaUp9/001CkUC/eNjbAAHx2CXEMss4Jfzxk9vezBSFBlU0PvZr6X1724HMF1gQ+ue5v9MvS\n        q/i5eRPhcRIGZtwHEci+71O8sTXAdyulhsnnpeLD8nLN6XHxvF8+Ri14nvjMPODKH9CXFJnWGfDe\n        34xw8Q4OeX/5o/fuY60cT2aAcbVu/MXcpRU0pKCj5vVIzWllPuw//narM3EYG5Z2UJEShu29G4NJ\n        VUNRBX0h/td8ZRtvgdtO35HXV8/p85ynIIg/O+yb/j3vtDJ9weBjZIShS+gTxe4EWGa9hQ+9ujWX\n        8Wn98fM4kC6tz97ncwd5FL6wk8DWHwWHZ8pH9zRqf/NI1h4UBI/UcIngn8NmdhfUb8eiDqhRLjkY\n        zyaBcPGwg11rXEwWu4MCpSaBZGuNiz/2k+lBsb251JA3Z1+6i16qfPUcm9KbD2RtuDYsSHGnv3xy\n        esjdC+oH8Uwet+nI57dehdBwdk9svuWk4RjdOuUsKAIONmruc3tnLNBRUYLN+tJGRCiMEbRusibS\n        l4f4DAcIM4cVCGwCC/B1by2gFpQdxe2A80ncHBGQ3bP85//8lQ8t7D7rlOq/++Owa8Gmfh3JM96M\n        +ZI51xhazXtFVp/Cz2fn2ttQKtUX1ZNZjEbeXwXw5Snq3HzfXCwtf/38O6p//TWtOQHf58GGumtz\n        qhRH78eLNIBy0oyut4dQ219UIrIwN+fG3muw3TUTaQel+JOXArG9u9Sf4Xng890rIZAPb3pwNkc+\n        OHUb/vwA1aNdb3LvwmPIb0VIr1rnDSK5pwgww7LQQ3+8fVbdOhtOcGXiPb9Ww3CeXi/4zT+pDWQP\n        yJdoCGGGXQHvKs8dlpOsl+DLN2SbT0rEW88OwddPE0EYb2DWmpXwh3+8wpRzvhgwAF0kYrIxWmGY\n        fvwn7PY3rPuFYrJEqslPL7ArmmufHTZ3C+4EfYODY0qHEfJ2hKH+PiN569cRC3viwTGRO+p01Ttf\n        DtJJA9+8E1uuscvJVnfGnz6gzUsjA4kLjkCprgH6fq+I9dswVIPCvH155OgvK2PtKbtnZJHFxg9z\n        SdOsgKu3dUL8ABdOXk3BwHd8o3C+J/noejqEwUfLyDqXp2apvUKDtUIyukdO1fBQCkKg37OUgBlu\n        hvH+aU8AP06PP3kjja01VPSVv6fu/K59elHs1S9vo1+eGwiJTQsasVVj13wVDbkvpATP87rFB7M4\n        +uwuyBkodrWFUelgfzm+Rw8+BvFF9Q81GvHSJj00yCnAB7k2h4lf8gpyZb2gp6Yr/nJWYgLeRcyR\n        tFZY9DkFKwX8/MTxiC1/8/X3kL3UFdpUihyNt53SAiWd2R9+mk7Baguiz6qkOFaXnDXON//YWSmO\n        DngV9Ze27IArn7YY7UOtEc8krKH7HjfUk9WK80IDKUTj64KN6vnkvDzkDNqPy4uI/gkN37xdABtp\n        fyG5unpFGyhpveoD8qEaOGmmmF2nEbgptPCuaz75BofVS5Xdi4xRlhtcKI6rBZo88rAVCjafgy3Q\n        4HvailRDl9AU8oSPcLwShe7Oz5s/Y2LYkLBshe1vPsl2S5wCu/W2ZDlpSs5Ni7RQftjtV19yn8n7\n        WgQrEwbkp3+z5Ey9ssnzD7W2n0ezxBS3gPvKARu9szU/03m0wS1fQryvV9hnv3zoW2/ovjwqA9fc\n        8KQKJzfDcVWbQHTSvQUnISm+9dgyByOXFFgMwwF11b3wx69/+HM9HAnasNzPwQrqB+FMb4fY9b95\n        X6mmcx0iMEzku36lnaBlWwXWn4nOpbEZEADTyaXWV+++eaIBETIv1EseNp8B2xaA2YOH5NTgYLRQ\n        T2DOV/rX71L++uXpp4acsPs5qsOCc38BbF8U1NLtPf/yPoJxgwm1WhSaf9ZbhM2pou7bSAa2ixfl\n        xyuIt68hmjNXSX71Esl2GQ7TZQ4YQKdsog4vjGa5q7xVE62vv/Ui84fFgAgOn7eElPCk+dx+fwJQ\n        KPnq124u1+hWg7u32pKOW04uasWhg6zUa3T9vEQwP+TqBehR1al92HzyBVXuCNdKExC4HAkg4WpT\n        AsetD9jyz+HA8x1LFMzME5G2qM37/TWOVaVMY+q1m4zT5Zl1YK08Aqwd+nzoDc5dePQVA+PiVeeL\n        wYEL3RY0dOdy0CxueT3B5WBcqWeFOJqPN22lGmsRk666Q396OnEIyrDIiPo++nz55b1f/kVCsTdN\n        CV/rRa2riv3h6UlrRBFa0jpCK2F2Gp7d9B4erMUl9WkinNNUOcFPJwWol8Mx+q4vjIqWJMq3fjr5\n        /JFIAvjaiHAQrAmgh3vJ4JJzj3rPGke/8QBthO/Yz8TK/61vyG334fjwzYN+/Qn3rvlB4I41IEE/\n        NaB3HSnWFaXlX782Alq4A/atZ9fM06hmUAeejTFREvPrH1J4ogPDv/H3OCTx65dv/upBw77rlWDZ\n        dfovH83JOo4LGL7riShn4ZTP2rEv4FlnBFstYn778zMoN2Lsre+RT0dbH+Fq252p9x4/JjcxGGE6\n        VyHdlZdVMybSd3ynKKJaupbAH777MPwkPgk/0fjzV5KwXePv+nLOfnx2sJiLtesY5BOQpBG0Rt3T\n        /c39+H94eBpSDV/Qa91M4efgwmv13mBDqT8D8/xzoD6I9EFhuTuYlDjFCljep8ZaAyKfEWXFgLwt\n        IEbetAPCz6/+yU/ald3w2JIgtOLNAbvBuTYJuaeBKpXrF943QzMsxeBrYBscL2jZFELENTcN4ff5\n        kFQftZxVzkGE4la8YbfbaIP00+dAWMvU+fI1z2yaysL22GAL65CPYXpd4GmwewKqOYrmXJI9qHjG\n        +uc/IpLSYfmzHursZ51L33xLiQfpTDZLWeR8VIQaLtPl8B2/jcmmOkPQreIbtrttPSwpbRgIxWNJ\n        zVuP+bLzK/LL87AGhVPzJ985yzeFvHlRN9y0Xi+4SPWWmujzjn75MPz7tyvgP//111//57fD4NXd\n        yud3Y8BUztO//3urwL+zW/ZvQRD/TcU/OxHImFXl3//81yaEvz9D9/pM/3fq2vI9/v3PX1BQ/2vD\n        wd9TN2XP/9nyr+8d//Nf/w8AAP//AwCe/y/15yAAAA==\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7c09bf89ed1e1c7e-AMS\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Mon, 01 May 2023 17:29:43 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-organization:\n      - user-kd1j0bcill5flig1m29wdaof\n      openai-processing-ms:\n      - '471'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3000'\n      x-ratelimit-remaining-requests:\n      - '2999'\n      x-ratelimit-reset-requests:\n      - 20ms\n      x-request-id:\n      - a9c89e6436668562329d35d627f16245\n    status:\n      code: 200\n      message: OK\nversion: 1\n"
  },
  {
    "path": "tests/integration/cassettes/test_local_cache/test_get_relevant.yaml",
    "content": "interactions:\n- request:\n    body: '{\"input\": [\"Sample text 1\"], \"model\": \"text-embedding-ada-002\", \"encoding_format\":\n      \"base64\"}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '92'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/embeddings\n  response:\n    body:\n      string: !!binary |\n        H4sIAAAAAAAAA1R6SxOyOrfm/PsVu/aU/kpFJIs9AwG5miB4o6urSwQREJFLAuTU+e9d+p463T1x\n        ALGiycpzW/mPf/31199NUmb34e9//vr7VfTD3//j+yy9Dbe///nrf/7rr7/++us/fp//38isTrI0\n        Ld75b/jvZfFOs+nvf/5a/veT/zvon7/+NuPiQ5nS1Anz5acM4uJ1ZNpa6bouyZMjLJdQMZs0H071\n        gcrA3keVHUtt4GxxmpbKpd8Q5urcTppOaEXZRcct8U/hJ+LRfchQhzZv4iqmnoz4sN3CaV17ePPq\n        P15npqcc9Pf9yLCTWmi8r4mBLoLgMxWNqKR6tKTwcM83rLRb8OZ4jLcgX4URN/ux8KgSvxtUsFJl\n        ji1XiBfJs1dO/JwwcyO5+oS8tQGQGluyS6ibDOB1N3AIDfAQNarXy5f4iE5iTpgpd5bOk8GtoPH0\n        HsOptJOxux9cqNitYI6nd2WR7zcusGJ7JGpq5px/KtyjfIMRUzeG7bHJkVto/O1AVxpqk1m0BRFN\n        SbH/vdeHi6MBXGZXI/jlC5wv2PWIOOlvTDvOQTJpbiSjOiUWBn67JNy/Xn3wyyUi2HaSjkVXVwX5\n        yBFTYytLhsxY9LBYXp/EROPEh9rYuqjFqkWiNiiSWeR2C/JN7Yl/Pr8iflyNAbCk7Yg1r4/JpO0M\n        G8xTsGGOfa35tHx1Mypq4cX2/uB59LA73SC1IoMR65B3w1IPd0qRVwqx/fuKT055zWVf2nV487pf\n        +fRQ7Roqeq6JqepFN54Wnx088MckesuJ3t+PqyvE75tLZ3o8JPMhMlr4iF2GZWU36/w45bmSc/HI\n        dLy0+GQ3VoMEB9XM552YTNkhCiFU45KiTaXpq9qOJbg894jo7eGgz6zoCpgyqhHttEbelK2XPRQv\n        pWLO+/XoRr69jhBErUy2w1R11K1iEbQNbYlNLi3nPpF6KNr9kaloj/mYvhoK8Ts1iZvG124+NMxA\n        S6FGeNwYjc6mdyOB3jIdo4Sq5ci3wQzWLgqZKgPhc56QEbFzLBNVjktv1q39HQQtCEhc58vvfCOF\n        o9V/8GrLRG/EdZWBtspkorfhAk3Ds/VBavSQOc6ClJOmNT3o7+xIdPKu0LiT9mcYqLRlD+uglnxx\n        WI0gLsUdMbfUSqbMWFMQUfDBrWaXXcv2xxEuihQwa65PUecf7zbo/RIRuz28k2lJ9XAhn0WJqcl0\n        jJpTezuDoF08st9Pli6K2b4CRweN2K3aJDRcbRuI5lRiu+tcd62elwKasl5j3/pG7RvWNdSZb7Mt\n        fY1Rfw9e7YabqoXFSyZ7rHhMdzADATOrZ/eo74bABr2bF7jE4Qf1lXWtwdkqKv2eRj7nPZ5huoQp\n        3by8mI+ysLuDYFaIHA2ZdsxE3oyGz+fAtFVYc25eZwOma3JkhlUZ3YgRwihXypoZxUg5m86rCriG\n        MDG37Oy1b+loo/ipFsQx4lXZiuvgKhedfyJeLIlRf0rFUZaKpiPGM4m42BQTVRabycYoyYJo5NOB\n        /v4PcR8z6bgvhi749InpSp/LaKoX8xHBZT4Tc/Pu9LES4wJC9dwQuzvPel9ZCwEtlrcn80f/xbn0\n        DnuwrBMmuNq9kikw1ZtS9ZgSo3rb+ojjZwHdOtdYGNmWN873cwPB4aUwL/G3nZhnkg2N2ZlULoYK\n        fUBUJZCjzsALYSGgQWu2LgzDAqhQzxKnsRbsAMKsJbozyeWc7ycXILUV4i7GRufF9ixDcmcYr4Ps\n        HU1ZPM8/fGV7Zn6i+Q2LCqzj7sFIwaSOfZS4gGY3AXMVKU9md3J24EK5ZNvDAXs0h3knT+mg4sXz\n        mnv9/Vk1Pzwi1iy+SiqkwRZEFH6IK9wT1M+fvQyOc26Yux2R1/zqoz6PFcPv6ovfnlEp/ttsmRXd\n        PL3vXv4ZhdbKomsehwmT4HMHTRFuzDEQ72YRoSUSsHOmrMjijn+UAW+++8H2YWR6IjvlNTQ7puFl\n        zVSPhviDoajhxbCzeKFRXtUAoowHLO1x5VF309TQaOcb28X6q+PJZ1dAEloiXqFHyHlSdTtUPJsN\n        nkRJRZ+l9RTBneaantTjs5ycMijAIujD9M+iTJh0kEK4CODjObotEY2VRJCDu3tjhhWZnRhebCo7\n        6rzHyzL0EV+wdY9++OBPgcbnHPtLcDe+S2JPtEs+mmK1CaP8Tqx+LyQ0dz5XFHf9iuz7riypgoYW\n        tNHBxLs5p6TvPmxEl0+bM3OzufJZSbsePbaSSHR3JZaTrYU5DP3KJMbr9vL4wjmHSBNzkcXVxtep\n        aIsimPfpitf0dI64eSyO8JkuM3OzRdjNwlHK5STOHsRVmlGflVrH8P0+Mcpli9o8vNfyZ/Uu6Glj\n        7vUex88c9I4azL8kozeHF7VHx70VEPyObH391SOQC++CrjYXmXfSPi9Q8hAt4s9rt6wF2wkgCWBB\n        jAKPnPvHowvxKwjJtbHVkhejlAHs9xIhz2uuz65wodDo95Bg761EQ/2UrsCSpvutVzc4t0kF8+hu\n        KRLte0lF1Li/98xUX3k5yo9RBH+tMlz0fhxN2UnsYbrdDySklfadb8zgNOHyWz+G/hnmjw9SZ3vM\n        /uy9iPu6k/3wll0/+y5hIz7vIK4OB7oOG+AzO1sCTJHVEFzPV9RF4qWBKr8/sBifomjOHcVA2ux7\n        zLxXbzSzQ5WDX6xlvDAdu0uHNMxA3NgTO4ufUzmzMwGkNy+PuYqc8p7vmkJ2hWpippycEfc/rQSO\n        fXl/+dLlfKEKM2LpOqPyFqceP8qqCrgPJOKPiwKNcpSGsHKDgKS+N3j88yhDkLPgTgda3fQ5ViIB\n        vvqRuIVX82bHXiKS6FXGY2xl0TQcZUCwJxJVosvTew16Hij44y2wEm5rfVhelwVoCtyY8+odfT7k\n        VqX85ntYIYt6y5Yo4qaj0GpHnG64dEmLHt7jwH71Ml26qIVsvX8y7Xsee2s9NXApA4lop1OqcylD\n        GIYqaJlh6auE6hdpRkt46My7lkn0Pd85uOtdSHaryuXf+rlDa2Qdc9y573pLrSSAm+BSCWuat/6U\n        fAuhvdHxeNcq3ortx4bUfXLm3WCORouFLqTODegkmjqfbHzK4LHPMUZXLY34cbiOkDyWFvEvt2fU\n        p8dnj4qWHOnzIhgRT+5e/dOfzBNbuexlPC3Rg7S7P/px/vIVGtomJLYvRGh2XX6EBVogpjdtk/Ai\n        cjGqgvLG7G6ToSlQxxbqu+cxvbHdZLIVl8KXf+hnV9yT8b6oa3C0jUGMZx+iL56KKCRhR6xg30R8\n        Go8GxHXsMFdXu4QVl1gAwZ4ZXj77GbWh0rpwNKuJbJmdelOw5zUAOY3Ev7gHfdaHCIOZtE/K2zmP\n        ZjHdSCh+XfZUXjw+Ho21coYpkFdU1lqtY8U2k+WhOr2Y4wg5n4Y4u8n652Ox3fmWebzFQQWPrSxi\n        MTaW0TTQl/tbH5qjMSmnpR4aKN/4CE9rF5fjPRgaOUkpwYuyWHX9V8+idN/0xLDEORq0amfAdPaf\n        uIvX725ava4GXMpQYubm7ekzy9gd4vqI2fc8cB4NfQb6p/bp0vSGkiqL1Q0sO3EpHKebzhedXYPg\n        CSXTRrLpxmpOM5SNqw2d2XUfTTVqayQf7gfmCkrnzfn52sIHKS5RkZ973/WRwXqIlHm32zGZw1AC\n        tMK5yqzzKY/4Fw9BTrwSr0efdLxorrAR5x4T936CbsS24KPlYpiJTTYNnxkvCtTsjQ9JVscAfSCX\n        baS3rU1s0jh8GFqnRzGVPsyTJsNbT4p+Br6VCEZJ+uxoeLH7P/rKseprMv3wrd3VJd7U2NLHzrvZ\n        qGAv9PVbTVL9+Lwxcky0dbLv5t/5CPcuZ+5itD2qy5kN3So1CBGE0euKle0jTR5rYoVm4M1CrAZQ\n        ZxeBCk76RqMFzg2ksn8zxzJuyTQsrnfw11tGrOnZltyY1wDhdWkz/3LTIl5MlyX68gtumhuN6rzf\n        zUhvioC+pNUdfWBY7aAo5wlPK81Cs6h6LdTH4Y37+Yyi/ucXpvh2wtxWKPrjh8w7v9I5SLcJX3Rq\n        pfz8sB95C8SK3LTBfzKdblmLvO6zM0awrmfCrKhrvTnWAkMxb9WLOK9hjYbM5uMPr4n79UujZY89\n        nKYoY9/zo3dmqi3htHyEXz6Cbqqf0g26Tb9kN2UX6lPNPQNJHzViu1tMkqkufEOuj23P9HaZ8unB\n        4xDkxCm//m1bjph5gLhznIntK6beV9cyRNVV27D9F48nW9n2imWSMxWTtIumi2nK6Ov3qKwhtRsr\n        Lz9Dks0eRdeiL/lU9iIMdZoyN0ViR396MTV3B/xcJ/uS366kQLg1TKZx4ZbMYvt0Qb7bFdnj18w/\n        l+VuifTX8Y7X3DK6b/3RP/ip3pdPNNS16oIZEWCm1t08LpmOij6Kvvvhi859/WTDgsc5IxB10aRt\n        NFvh6jpkHhrenEvn9xXgivZYweIBzYecVJBLhsFUGT31mdUoAItsPsw/Ld/JzBjN5K9/pfzDuN7f\n        bWwjcVHEVIzrORpq/9lA8WRLvFhMe33EgGXQm7f31VerpNV3mxmmSB2Iq7y1RHybDxfVp76hMJ/8\n        jhfbTNqw0ghYXI8vb7qcNhiEvfogptbJ+lCncNw0ZuV++StH7Q9PvviDV9u9pLPPUt6Cu/b2+LWl\n        74j+6hUX7E5X8s3Wx1k2JJQkXciscCdwKp5uN8iVZ822Ufvy5jgU7jA8DZGosl15Q5ZlGPT6dqUK\n        1fbJKts/MEot32HYMxdRYxWtBJemrohhXJ6o5/mth6PFK6p88kyfLmqbweUzJGy3vofdeF9bOyQY\n        mYFlRVZ4g+NPAUNurhiuA5lPMG1scMjkUSYoWiTqVbNF4vg5sH1YfX9P3apScFOLn5/Ue9ktDBjy\n        rUynMZc6vnDcClhoERxszic0DcdZAMHsRIwkUutD0D2XcHkXDdutIo83cp/vkHlJe6YTs+bcX5hn\n        eSG1B+aJ1sC56We5nM+rCEs4zL3RAu0KwX1/+sNvLTtbAHVYLJmaXnA3u82zBr3EFV3W2dObanVn\n        IMfCI7M/49Wb2QlCJD0rRrYDqcvZXV1FENfbDSOCEHh8VC4qsDo0CDG7uuMmtZeoTl2fOdWO6WPq\n        uz7EpXv74mPjzQzSHvyXwIlRPAjinz7MlWFQgDQf5iTc/GwM9OUbslu94nJaXvMlXMoLx3BRsE71\n        j35HjRafiJpeaMeKywGAb2VCBe+Yo/qw3TfQLRObDl89N7vKeFa6zcSYtipNtMQGvcvizB3K1Mst\n        6Xe3yw6q++FDVNmZOTNF2P74A8fe61NOy7tU/fI45hbeDo3dVbv+yau0i2AkortbBOsvfuKFIX3K\n        H38r4lidibo5WfqErvUZjo74pCv0mBErdqEAHSjlHz081CrewXLBZppGu8LrO+/mAt/ZAtE/fh19\n        /awE7fbMCbFKnFB9NfdKMZz3+Hnxz96k7S5LOI32m2lHvtAnyGcX8rUjkN95o2ES3OHhBBlLadkl\n        s1hoLcix1jFTPxy9wTl/QlnqLwpd05MY9fj0yoBVrs+sAK91JmFLQl8/h8XlNPAJdE+GKoufRG+f\n        WjIEN6GAfCX4THcIdHxUHqqsTTbB0rd+ukU9ir88gQqO3yDu66krL3iS0wAxn8/NW8sgicsbvkTK\n        mvP2PBqyHFxPX30Rd3zC26uymPyBmAhHnEvqJkSP/duh4s3Syok46xyS2+v81Sv7jpuv1Rb0blzQ\n        7nZbRuyjKVuEh5gx/BqwPtWUnwF/LIP5p+qiDwM93JHU7XdY8IygG090NUMSSAaxmyT1xnTuvvnk\n        tmc7cWcj/vMvjEkJOyzHhlMlWN7l1szfxPb7nT7+8peYwYuYGU0jtuCNIbc2TfDGfQ5lvzusK0ju\n        TcT8izvp7CjbW/TNa+gru7NuGixJRa0veMyKHN+bLoaMQc7CO9vFYlEO2anbgrMj7JsvbX75ZgGO\n        urb/jBf1ive//ITOdJV3PLmgJZKeNSPGNx/48cWmqihh/sRxt4F7e0PDsNHwdNrmHdXzEqDOsM3M\n        dPfi07CoXCQY+YJsWZvocy61ZyRsE4uZmbDvZn0qBDiBMNPkehjKnguqoCzE1xHTmvQ6Ty6NDR1C\n        b2Ju0yaZwya5gv7c9RR996e39ncXnTazgKXufdDFePOQZZGPLtstn0rHzIAGv/XBEj4q5Wug8R2G\n        5nWiDCo34v6RiWgKpBXTjqT85gdCBc6+upLIdg98VuJIAKnRQrbvHbOctJBfUdG6MXO+53tMXzmF\n        bvVcEH9aKsmIMwOgqtGWKrTsojHVix5S5wq4XeRrNNTrcInYrWZEO72GhE0SqiHIgpAY+U7iQx1f\n        ZXD8/M5cPYy98bffjmGumTatonL+5rmoPrI32++DNR9q/9Oi4LQaMJy2sTcNiyBTjsZr/OVv3rCc\n        614W1ANhxlOZ+DRYowoPy62/+PLWabzxfWD3qaCyZusd+1S7HjV7p6J5esGlqK9kCvl6azOiXM/e\n        mCLPRt/1JbrXRH/8FwSnecbfPAK9Lk7aoHZXlWy30pNuWraWjz4LVyDemooljc9y/sMH+pKijM86\n        iUP0WZANwy8v8L79hCXIZe3gEbGeM+mBpT9+qoWt+NW/doDM+FXhMW325RK34Etc22B6NNMkGqtZ\n        G8FKcp1Zh6JMVjUqakjVzZ14sbmJRvlyOKJU14/E9oclGl5ICKDRkhMum26tD/YZBFS9QWD2fhrR\n        aDn+7ZcvEuwZY0e/+TZydEFjpj7rSf37P/izdZh1KEN9WOrDiHA1xkxvkJWMeN3doXjJH+bPxlBO\n        mtJXKE5RQyd+h4jqpBdkM10fib1/6N6PL5D8OF8xzMa+W5tUFSG4SC3NbJA6tnC29Z985scPc+xm\n        AnzzXCwvcOuNaRCDbEbGjtyE3vcmzU1kYHHB2TZ4LPjnh1/C3rzRBWz9aKyCxx1+ea13PezLOW5M\n        H5IH2jIi3GdvGmydwkli2z/1w4tKw8CYnBAC2z6Z6rar5aHEFIvrvuBULLQGzPN5Rb55hcd/+/fr\n        T7h3HSMq6FOh1OGLMVc9r6I+FfkVllxqWOath26Ol5ABy4UrM+9bB/W4IxLgonli3oYPzvwjWyLz\n        iJWff+d9mmq+chr3BV5889hpeYUCkmy1I/Zn30UDyNVRyvmGEFXiH692ib5TOOEn5t3iVyfqpAf4\n        5d3qvSzQF5+O6Mv3xJS0yXtdiqUL4WX2f3lqOSyvjYi++gA3jYK8lqmxiE5SazHtOD3LIXi/RoBj\n        l/7R780JvVTQ6zQiqhRuEHUV6Qj5xlXpOjwzj+qkAri83yXTRLPkc6M2qtytuzUVvnzDpTO7gT81\n        NsPuXHDmz+cd+GPlU+rpT8QWEAVKt7o5dJQKV+dRrmD07Rcx4wW6zj8l2qJsc4kpXIaUT867Cf/k\n        Yf7Xz021/2lkRx333/oOuvaX/6ZbiNnRQGnSjTjbQeOrA62+/DjreRDAdDQ+jCywGolhpbcQXkYf\n        D8Ne69hxNYagjbsIr9Jr1PHjSgoguNs3jMRW7vj0cG4/vfjD53IY7McV4ue2IPs9cTzacKlHSaii\n        7/55SS/vbkeIO7oiKsJpyRdvo4DHzmiJxdEYcfOlqBBcFi/m1GTFe5mYBRQdPpFfPv315xRVzzwh\n        JF+PnBWXVwOCI3aUN6399cvB/ecfifnNU2elpc2PH/H0zccG+BxakLPThRGl2SWzfhlnpXGkFUv3\n        01sfZ+/RIDlIAyp/83++cLIAQt+byZ5d1t4vfwdrP03MMHZbPmTFIADfLlyyjZwVGpaWUmxaHzxy\n        4ShIeOL51fq0KjFthXvCp0tpiZBi+u2fnMqIRVsewLcfTB+WNib9LPsydKN3xcu8OaM5D+8Vqh/H\n        BTl885XhmwcoR3udY3m7p8msxKxFzd6rqODyqZxscwXQLbY5Xk/zp5sCpxTh+/6Pv2kq+Rmib/+T\n        bXt/k8xMMoVfv5D96bf+8tpv/kqMcnsv52+/GnD+qsg26jgfU6S7v7wQr7n8LLnvNQJ895fOga8n\n        4q+efDgmTP/4u2QthZ4AD02U8Rw8HnwIVKkF6yC8mauedt3MHHOLqt6n/6Vflq2FIYi1J9O//WD+\n        6WuMgsTI2DagWjJibm/h79+tgP/8119//a/fDYO6SbPX92LAkE3Dv//7qsC/b+nt38ul+G8m/rmJ\n        QPtbnv39z39dQvj70zX1Z/jfQ1Nl7/7vf/6S/tw2+Htohtvr/3n8r+9c//mv/wMAAP//AwCkxTP2\n        4SAAAA==\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7be211a83807169e-SJC\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Wed, 26 Apr 2023 21:55:16 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-organization:\n      - user-adtx4fhfg1qsiyzdoaxciooj\n      openai-processing-ms:\n      - '311'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3000'\n      x-ratelimit-remaining-requests:\n      - '2999'\n      x-ratelimit-reset-requests:\n      - 20ms\n      x-request-id:\n      - 665023d2f6ce38148bbb6db93c66bb82\n    status:\n      code: 200\n      message: OK\n- request:\n    body: '{\"input\": [\"Sample text 2\"], \"model\": \"text-embedding-ada-002\", \"encoding_format\":\n      \"base64\"}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '92'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/embeddings\n  response:\n    body:\n      string: !!binary |\n        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\n        /wMAVLQZa+EgAAA=\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7be211ab1afd169e-SJC\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Wed, 26 Apr 2023 21:55:16 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-organization:\n      - user-adtx4fhfg1qsiyzdoaxciooj\n      openai-processing-ms:\n      - '172'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3000'\n      x-ratelimit-remaining-requests:\n      - '2999'\n      x-ratelimit-reset-requests:\n      - 20ms\n      x-request-id:\n      - 5b810c395d48248e473bc4e53de0eafa\n    status:\n      code: 200\n      message: OK\n- request:\n    body: '{\"input\": [\"Sample text 1\"], \"model\": \"text-embedding-ada-002\", \"encoding_format\":\n      \"base64\"}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '92'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/embeddings\n  response:\n    body:\n      string: !!binary |\n        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\n        4SAAAA==\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7be211ac8cdd169e-SJC\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Wed, 26 Apr 2023 21:55:16 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-organization:\n      - user-adtx4fhfg1qsiyzdoaxciooj\n      openai-processing-ms:\n      - '114'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3000'\n      x-ratelimit-remaining-requests:\n      - '2999'\n      x-ratelimit-reset-requests:\n      - 20ms\n      x-request-id:\n      - d39b785f954e1f1cc64746735c44b522\n    status:\n      code: 200\n      message: OK\n- request:\n    body: '{\"input\": [[18031, 1495, 220, 16]], \"model\": \"text-embedding-ada-002\",\n      \"encoding_format\": \"base64\"}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '99'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/embeddings\n  response:\n    body:\n      string: !!binary |\n        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\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7c0b986749b8f9cc-SJC\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Mon, 01 May 2023 22:52:31 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-organization:\n      - user-adtx4fhfg1qsiyzdoaxciooj\n      openai-processing-ms:\n      - '18'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3000'\n      x-ratelimit-remaining-requests:\n      - '2999'\n      x-ratelimit-reset-requests:\n      - 20ms\n      x-request-id:\n      - 0d93269b5615ee055622aca99d9e4aa9\n    status:\n      code: 200\n      message: OK\n- request:\n    body: '{\"input\": [[18031, 1495, 220, 17]], \"model\": \"text-embedding-ada-002\",\n      \"encoding_format\": \"base64\"}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '99'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/embeddings\n  response:\n    body:\n      string: !!binary |\n        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\n        4SAAAA==\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7c0b9867da38f9cc-SJC\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Mon, 01 May 2023 22:52:31 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-organization:\n      - user-adtx4fhfg1qsiyzdoaxciooj\n      openai-processing-ms:\n      - '20'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3000'\n      x-ratelimit-remaining-requests:\n      - '2999'\n      x-ratelimit-reset-requests:\n      - 20ms\n      x-request-id:\n      - 25535161a3c6c4c4d2d95830fc85649a\n    status:\n      code: 200\n      message: OK\n- request:\n    body: '{\"input\": [[18031, 1495, 220, 16]], \"model\": \"text-embedding-ada-002\",\n      \"encoding_format\": \"base64\"}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '99'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/embeddings\n  response:\n    body:\n      string: !!binary |\n        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\n        4SAAAA==\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7c0bc85bcee4253c-SJC\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Mon, 01 May 2023 23:25:16 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-organization:\n      - user-adtx4fhfg1qsiyzdoaxciooj\n      openai-processing-ms:\n      - '1067'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3000'\n      x-ratelimit-remaining-requests:\n      - '2999'\n      x-ratelimit-reset-requests:\n      - 20ms\n      x-request-id:\n      - 482e97acc620bbf5e2f7d3dd44145666\n    status:\n      code: 200\n      message: OK\nversion: 1\n"
  },
  {
    "path": "tests/integration/cassettes/test_memory_management/test_save_memory_trimmed_from_context_window.yaml",
    "content": "interactions:\n- request:\n    body: '{\"input\": [\"Assistant Reply: {     \\\"thoughts\\\": {         \\\"text\\\":   Result:\n      None  Human Feedback: Command Result: Important Information. \"], \"model\": \"text-embedding-ada-002\",\n      \"encoding_format\": \"base64\"}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '207'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/embeddings\n  response:\n    body:\n      string: !!binary |\n        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\n        /b/P//X9a//5r/8DAAD//wMAaBDGhuMgAAA=\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7bf024783c8096de-SJC\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Fri, 28 Apr 2023 14:54:47 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-organization:\n      - user-adtx4fhfg1qsiyzdoaxciooj\n      openai-processing-ms:\n      - '325'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3000'\n      x-ratelimit-remaining-requests:\n      - '2999'\n      x-ratelimit-reset-requests:\n      - 20ms\n      x-request-id:\n      - f59ce3c6f76fb37599125046aec3d2bb\n    status:\n      code: 200\n      message: OK\n- request:\n    body: '{\"input\": [\"Important Information\"], \"model\": \"text-embedding-ada-002\",\n      \"encoding_format\": \"base64\"}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '100'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/embeddings\n  response:\n    body:\n      string: !!binary |\n        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\n        c/lf8//6z3/9HwAAAP//AwBim/ij4SAAAA==\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7bf0247aaeea96de-SJC\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Fri, 28 Apr 2023 14:54:47 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-organization:\n      - user-adtx4fhfg1qsiyzdoaxciooj\n      openai-processing-ms:\n      - '63'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3000'\n      x-ratelimit-remaining-requests:\n      - '2999'\n      x-ratelimit-reset-requests:\n      - 20ms\n      x-request-id:\n      - 974557ca996688f2b7e568f6d601ad88\n    status:\n      code: 200\n      message: OK\n- request:\n    body: '{\"input\": [\"Assistant Reply: {     \\\"thoughts\\\": {         \\\"text\\\": \\\"thoughts\\\",         \\\"reasoning\\\":\n      \\\"reasoning\\\",         \\\"plan\\\": \\\"plan\\\",         \\\"criticism\\\": \\\"criticism\\\",         \\\"speak\\\":\n      \\\"speak\\\"     },     \\\"command\\\": {         \\\"name\\\": \\\"google\\\",         \\\"args\\\":\n      {             \\\"query\\\": \\\"google_query\\\"         }     } } Result: None Human\n      Feedback:Command Result: Important Information.\"], \"model\": \"text-embedding-ada-002\",\n      \"encoding_format\": \"base64\"}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '483'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/embeddings\n  response:\n    body:\n      string: !!binary |\n        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\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7bfdedf56918cfbc-SJC\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Sun, 30 Apr 2023 07:04:15 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-organization:\n      - user-adtx4fhfg1qsiyzdoaxciooj\n      openai-processing-ms:\n      - '25'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3000'\n      x-ratelimit-remaining-requests:\n      - '2999'\n      x-ratelimit-reset-requests:\n      - 20ms\n      x-request-id:\n      - f2850337441001a8e5bd70bacb4dede8\n    status:\n      code: 200\n      message: OK\n- request:\n    body: '{\"input\": [[72803, 18321, 25, 314, 257, 330, 61665, 82, 794, 314, 260,\n      330, 1342, 794, 330, 61665, 82, 498, 260, 330, 20489, 287, 794, 330, 20489,\n      287, 498, 260, 330, 10609, 794, 330, 10609, 498, 260, 330, 38096, 42914, 794,\n      330, 38096, 42914, 498, 260, 330, 82, 23635, 794, 330, 82, 23635, 1, 257, 2529,\n      257, 330, 5749, 794, 314, 260, 330, 609, 794, 330, 17943, 498, 260, 330, 2164,\n      794, 314, 1835, 330, 1663, 794, 330, 17943, 5857, 1, 260, 335, 257, 335, 335,\n      5832, 25, 2290, 11344, 37957, 25, 4153, 5832, 25, 44921, 8245, 13]], \"model\":\n      \"text-embedding-ada-002\", \"encoding_format\": \"base64\"}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '594'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/embeddings\n  response:\n    body:\n      string: !!binary |\n        H4sIAAAAAAAAA1SaWw+6SrPm799PsbJunTcCKl2sO04iB+1G8ICTyQQ8cFDOdAO9s7/7RP87e2Zu\n        TMQOkqLqqad+3f/xr7/++rtOiud9+Pufv/7+5P3w9//4XnvEQ/z3P3/9z3/99ddff/3H7/P/W/ks\n        k+fjkVfpb/nvx7x6PKe///lL+O8r/3fRP3/93fe7HdujKCtm9AaQH459JDpOlmEvSuldKTb3hq4y\n        9EnGJcUlek0rkR107xBO5h6vIbBDk1n1aujmt2ovYMrrgXkvfcdXzeomQ4hDgdhOt+um6pZGCuyU\n        BTm4LOLjeNqO0M6XM9NKpUS1p2aqIhT5ihmvte7xp7SQ0USOV6KdmykZykC9QPFsK8rTi1583uWI\n        IYufKZUDUnBa3+gI0C5KeuJSyadFvr9D5/lnYsJcdZNT9xfwK2lJto7AQ74U/UDBMV0xw3hdjTkX\n        cAR4Ye5J9H1eHj9uJjzR/UoscbNJmsPSTCH11ndyDkaOaOmWNXzeF4PYRK66sehif8NOtwXBgsL5\n        rJ2EFqARl8yL37uumc4pwFHiI15eu9ZgXqX6iolpSJUjNbxJuWlvRTeeB7aPk84bLuJOAC4JAt5U\n        6z6cpEAS0DdeVOldxrvD6NmQdQcZi6el4A2rSDAh9D2JeOGq8qZvfJTQd6RvvPJiiN5zBLp+Lcnh\n        qhQevTAXQADxzXaX0SxWIjxOco6OAdur3tmbPEmrf8/LrMtG83i/E2Q4GZs1/sV/ctqdC6VVThiN\n        smNMt/KBoXZjDy/cdenNu7XsgmjJe+Ys7LwYVsjxoRs2IztICkrmzyeZAWvziliefEHNFao1nM58\n        w1yao2I+yPkdAu2wZYew2ySj40tPGEVoKdxHqZjmh6bLZBfLxN2ZhTHKPr7IaOEX5F4c02QcPmsV\n        PsFTZ2SZ9Al3F+IITSv45JpgEw1NXaewyQqH1hHwYjx0kwmLsoqx6Cm1MQPOffRslgYxcLvibPqI\n        LrTbNiD2ywu7WdpPoNykmeNGDIZwPEebFDovOFN5Mj7FuG6iGmK7Foh3saqEj6/lGiXX6kN2NZ2M\n        0SFhLU9IiTE3QrUTptjQlfmxSggeb3Yyyqd6RPmu8PFY7XE3V/PGBH1VAlX0Y9RN92tbyuvja2JO\n        TzPObueNikoLm8Q2kdIx9aM/FefxWpLt1a7RJHtvH6Rn5DMj1Hs+L24Eft9/9Z7M67WuL+kFMnYt\n        d4jT7ODP8LGTmJiNUxZzFCcWbF5BTDxFcrppWKq9Yjb5me18IvNJdNAC1SsTU4k/8+7P+3KV4kpr\n        MTt7rAkzGQK7m8gObY7dfJDbpzy+Hxfm0C4y+vjUl/BEzyvDghIiSsF5yp8u1r/5oxerTwxPWDoL\n        xrAtQjGdcYBhf8A6uSTbVVF+18N+Yi8sBdU1mZnRvNGAtDWLCvbyJvZZRCjZDu8/95/5uTpBPRgl\n        /ZS3E+rH02EG7F5cZhru2+CW20poI1t3RiJyRuO8TWx4ClFEtGR9DFft/T1DjitCuYSNbl6vXR1J\n        Y7v8xqfppmOS65DqiztzJ2NbSImX3mFfxxPRjtsP5+G5yBVto6+J+vSxwQVBDGCKDhHbNmrr0fm0\n        z2VooSSX+rUu2MPXAiDtSEj01hqDa/acQ3o/OjS1n+uEt/d+hMCZI6amn1s3730Fwz5dbOlGf5w7\n        blznWt4f9joWHIWhwa60HNTW3NEmKzJj+jBuIpGXhBmATIPdrqEEa0G0mCVybPBzYQvAy/uO3IIo\n        DUe42wISbCrSoxt9wnHT8icYxTpgztZ00Swk71KG2yvAqD3UHXMi1ZXp9nVgum0J3mfrZ3/ij5cu\n        a4r+ajo1OlXhgYoPsUnY9A4u4LOwI5YfrULaIA7gP+UF2/Gz5Q1y81IhPu5tRq7TOeHm7XGH3hFu\n        zNBylc/65fVEP73XfWgSnugFwHx4UmZMY5HMXbW35H0KW0LY3CWjlacUUPjM2Rbv7WTeJLKJwix4\n        MK/PT8YIy1GAjSxKbJc1STeii/FWzOzMmIalbSf6E1D5aBiUuccV5bPxWObQ5IFCDmPtG1/9C+Ap\n        xBFdNHNodFtDnwFp74xh6tYG/yhOiyxnETM83uqQVgGmsFoedOLOst/Nj3VykZeBPBJ87o5IvPBB\n        R6iPc6ygJOl6KY5y8CthSQ7qKU9GeFlP6FaLiJideiwm7THZyldfiU2FU8f3ND1BH4wxs4Ik5fzq\n        SCnK7PLFzFa2kkmTHROCOJuJE/GrMYWFbqHzECpE3ypLo+0H5wQb+eUQYl2Fblb8rQXztJ+YGmnY\n        GyMvo8onlxjR3GibdDs/NSG5fj4stuZNMtzs/I5MvzwzvDGWXpMKqg4VfeRky4c24SdZusBp6nOi\n        utVgzHdcmgC7/Zvt9ZODaFyNMdhXEcg3n4xx3fgtiI0rE/zBu2LyJrYHL58p2W6p7fXS2vNRx/Qr\n        UZch47xbbBayVNEF+da718/LhwSLtUkJyUEyaNqkVNH2LCfaMM5FjYdwrayF5w2P1+LQjettWgMP\n        Hy+azThAHEtqDPuXZTBXP22M/mpqNcIiKqnA34rBzstoBFaGS7JvFimvN7jL0XvYd+TxHDGi210v\n        gHYZXfL1T2i8QJZDUb1rtjV2M+o9uaCgRm/ObO9eJcNGb2JooD+SfSd6iBXhKYL7iI+ENI1UsHu1\n        GJF49TfERc+7x7OyuUMdXvbE8YlXjHftlcvr4jwz43w8GHMUjYGyRmhLdrp4Q/M8nu5QL3KZ7Zhx\n        D+f6ktnyJbAroo42C7v4yddoKQVb4qmnqeg11dKBXq+Y6PP2kgxFfh7RfFF1EgXnRTjYxi1FVyw0\n        7Lo33uGQvyIX9FCSqXQ7XfkcKmIJSepuqCQfaTi1XWmDU6UVM7erd9cv+25GX/9CZSQdDWY5qq58\n        3xcd3SzjbT9aoGD35BI//Wy6Yb8hPtq/TIMZ/iYyxnvxpspS8rdsV+4Szu9luFCqS+0wrzY5p0Ly\n        foMbsAudh8zlkruTL7/8p4vKe/BR39spRKapMvtS1QYXrnqOXMnqiFPMmldvE7VFX7/MbB6cUDdX\n        V4Beazie16WaCKUcx8hDlJJ9xdJuRFcaQe1GHgvzw6GQPp9kBG0/5ExbozAcvv0Dff0S3hzqSzjS\n        WqzhcM9SZnk0TViZ33N0LBMDX5iqh6uyWF1AScuWmSsIjH7dRC2KMyVnd7MRkwlvNeFPvR+6niWj\n        PIc5iPOjpgu0D9GYXlcUJThYsa26eHpzhnkJOxt57HCvYo+vHJki2FVHdmgQ+9NPFJXHIl5/+/vw\n        rV+lelAbizh68maXEBXlsvzByr2SvSmPRfrzr8SUtpU30v2HKpH5HPD6vROSRvQuI3y6kbGDGR86\n        etmLI0xorzKSSy7n/vviwtsRL3jdK07BSBIGgLQyw7I1b8I5Nu0IzevuQba2EXbD1x9BFq8OFOJM\n        SjiCVoLzPS2wNJC8YI9B0GURsw/eLPCBT1u/OSFr8ZCYq/fU4OelP8P6uDNp/u0f07LW+p+fZuq0\n        lMOZryAFpmcKXXa96q2wZMfwJJ7GdqsMiin29RQyZYtorphpMV0f8Qn8g6rQ03uaOn7aJDmKxtmg\n        i+OnLOpNfwmQ/BCeLDH7shtSP9JBX2HCHLV0C16IWQnRQVUZXrbCN962Do9A7JkaPvKkcYNjjZb2\n        K2G7g0zC5sOQCW+puBEVL3NjNLqLCXw5C0RPGqeT9HVfb0S5xbhaZdBN/iT08OlmRtReN40pu46m\n        0soeJc6sZIjKy9YEz77eiDlVFp/IPpNhsJBD+dVee715NiLYrl8WRbBtOF1q8RPVifMhh2dbdF3V\n        XWPY1IpIdrtQNqpqrwnoq4ds+yodj3/zGbJiwsR96KSjZY8EWDz8noXDc1P85ielbBYWXjs3BbH1\n        kFMIuvZGpZN07cYl3qhw3z8xIc+nyEd3o8pKt4IIs1g9d1MmtgKs83dEDp6mF1MWnmvI09UCi6+y\n        McaXf61lej1j4kZvlozUc9frPnR2TF/3XTe961CHkvsC25/2ntfeQzuHPIMPs/S1Z8w//ehG+UY8\n        x7XQ6oWOF+Xbr6moLhbep1L8SPnNk8FRF4pp92ru8Ej0gJjBZgy5q8SAYnWb0fG2vhljsL0AgBCe\n        MPQHzRvzQsbwfR90/s7n03lgM7JxgZl+jpuCa7acynLl7Qlu+grROWgoWp30E3OjVi7ox8AlBHYz\n        MatAez5Lbd+jeOelzJI9w5DkIrBhpRcq3vz83dePIxy2a+JsxkNBAecBfNS3RpIPq8P5eNT7nx9l\n        l9PYh2MSZwLUmrSmo3J/Iy6lhwjmJ+h4Ck9bLrCj6ioyPXjMUDSSzNfTQ4LTxsNENQQtWbXyK0XG\n        TmnIdrDEhBuCXsqZskPf+fsW8hcILoTcfTK3NZOE7oRXjxanS//lC1UxSGSzB1pLOV2v7TaZt42s\n        I2dcnSl8+cZQBvYJTinBdO3ddyE17vcenMdjyZxTlXat2vQ5rEnFCBl9D4nsI8Xw9ed4w43Bm1I2\n        vFEmNoSp0kPu+Np75OjsGYRsccCLwWmJjeR1mxLvUFfGXAVWD7cEJqbZZ8Sp8VjlPx5AdMVMu8En\n        VQ5DxF1ySJfEGx9NtoCZDXdmbV9pyL/9Qw7so8m+vIHXfXZ+w0vWE4IZ2iHeaav2xz/Yb97ru5uS\n        w/aCo5/fCufnwi8hzpY5sU7jPpw01K3BGe810e+71qBvrZthIz8c5pRalky4niSFRDJmrolwOHB1\n        MhUVLWzacjVBvNprkiLTak3Xh9XTmw7ZbYbandds501xyPd1Z0IfZgL76cXk0uyt/HiRAehtTC9P\n        KUG72iuiG7md8NnWY7CxnRGP3Eo0D9HtCb/82C1Siw9h4VowNX1Pp855hO/AEGx4tteRrnul6cbn\n        IVDRb341WIXD6UOjALbMjphTpKukf8/zBTwh0LFwtv1uVBX1Am7iN3iyzwn/w3cYXQXM5O+H0T+2\n        m4V8LG8GXfw3v0HiS9r/8qMYr5kQo13L9/Rd5lPCs9r04ezWOds+RCec+LP7oy/s8dU7vm8PMjrr\n        O4LXq9ZBws8f2bLwZvbi6iaNsn658DleE6yM+ZvTIGpHuD9IjaUgSRE/1mMJ93NEyF6PRa8vyqUE\n        P/8UEbkqaIHoHR6idPrqv56IP70vX/lEDp8HSVb0HO/BOx5j0s7CJ+l5lZ6U+KZlBH9OARp/8cRi\n        uiFWbmp8vCzMCxqOlyfTb2sHjafj8Q442b2Zeo4jxN6n5R76d53Q6RpPHj/aGP/p16Q6ed5qebNP\n        SNnONR61ru+o1+UXqKa7R/zb+uZNN7t9wi15m0wvZbHoMWls5A5uy8zH4oMmqnZv1D3cC13tjXcy\n        dFMXozKLOCHzLS3G/HNWIVDQjs4+OAmd9u/nL/8o/eCqG9nRtuGoNxoz0kveze2nCeDL4+jYJJhP\n        1VpcQBA7W/LTa5Fgs1dO52lDxe0l9AYQjzmKJnv89u97N6tNn6KY9Jx52bE2Rin285/eki0jrdFI\n        PNv/4T0K1WI0hvuljpQNuuJNkV4T2g/aBWX9JaOrx+Nj9LfDPofLW61ZKGwxF31SpTB2xZnYl8o2\n        hA50+ofv/PxyPcWejuoPPrBtggVvPMenk/I6nCKi48ExuBw/apSepAfbBmOI2C1atGh/yUe29RTb\n        GJPNMkJfPobH4+lQfOtfhp2wk7HEn3rH+1Y3lVdd7OioTSs+1fdSB+4WT6osuV/Qe6imEEMk0fi4\n        oqjf64YE0oW0mPa7Rfd85WoNNjocmVnW0PXf+toIhesy6307JFxzzxf4zrPErg+vbirF8YQ+Tq4R\n        e3Ftk8lpiQtCuyyYJ0ZOMi23kCITxRe6TAfJGKmTWsqwCyV664XBG52zv4Zf/x+F9B3OGUZv5Jhe\n        QDdwzfmEhukOU+bdiNfngpd+6xmSmu6JcWNDMgSPvYB6rePkxzOFN32tER9Si91e8d4Y3eiZojKb\n        Uqbbz8YYD7Zm/uZ7ugoi0s3EGGL05Wn4NJAjEjflLd7ooSCTX/8clJtTglCgN3PK3b5bm2cvgova\n        hORANZm/h+2h/vEZPAu4S/qiXElgBNGCdgoIqD+fribc6Ykw0/BZwj/3awAfcftgmvAIjUYVaYte\n        tR3T25fXjLfQGUHNUEZUQ+47nuqbO+Q39U2s5JqFjSZrJpBMIlSxCj0cH7v7jMS0qpg3dzWa2ta7\n        oMPe5sQpd33B37djrZz2L4+i/l7zH79DbMVDhrtmYczsNaWKl0fa1x+RcHZ382VTrdcrdhy3C++b\n        7ydwzm1Jvjy567OHsIDJn3u68W6SNwfCTGG9my/ferKNL29UgWQCweuAcGNKuJyDlj4+uKkW12L8\n        8bhQ/rhErSwjGbU8xCDYvcjcz8L3xMZKTn/y/zC/EoP2tHfl8z0vKGyqjE92XpnoN49k5yOE7BD4\n        sULTBoidbO2QM/mjbwRYvXGnxsAnofTkP3pIyKHh3bENI9gyNyKO76h/+ChoB8mhtHrsCoG3AyAV\n        gc2M3aSi+bb8rGF+LnRClHcWjtbT8mGuZIPW2fpkjOJ5YaGfvzXwM0u4V9k+uqZ9R6ybrYWTAlOp\n        mA3SKT97Gl9dnUUOfUJjCugdGVN/Du/oFw8DP7VkVU/3Gj7g3L/z3ux99UeVR0VtiHnGiM8PacxB\n        5G9CvM37xefV2CygbeITXhTbuVsNh9lVjO6yII4Xtrwb77KPct98E4+8Zo/J0vAGKxESCp80Lab9\n        bUORFYY2zb79s79u+7t8OPU7OimhnYiy6zxh5ZkhXURRkPB0cQFINo8Sw5fHT3IFe2CrKTzM0lX1\n        phXSfEjvocPsnTmHvTwn6Z/9F6vMc2M+Hl0K3Ku3X166RatgjFoY1eFE7G//548BdAhJlJCruqBo\n        7v1NjM7h0seLfvcsxh8P+/JLDEs4ePPydcB/eJx6LYaCxqYaIzXLBUY2lmbwVJ+eCDuH4scXDXES\n        pBTWt/ZK7NdxgZj6cZ/QS/mduEu4J3VQOhe4e9eKad/84k++CeTwxW1CwvDs8Qd7SsBPpUXcTXX0\n        poV5pChzrhuy/5Qemnva25DPw5J923DXKOurjeaDqbHj3S87Fj9uFthzeGSuExbhSIfIgrxJjnT8\n        +s/i8u5qubVuPd34xOuYs3pQ2b6aOXshY5UM2mNjw9ff09tXj2Zpv1kAGy8V2S8lDUnO2w1ka6B3\n        hitPQd/9ihZerLJwlqyPiXAKBB/oMzng5fd+87k59LJ6tHfsmL+sgovynENFXzndiG0ejgaxXLD6\n        SiSWvrh8/Z0bwxjgmrntZeuNXRT30D0Kg3krpzHGVN6v0eI03IjV1kPy4/MQC+AS9dznXd/rqqq0\n        VtKz/VLK+GiGdQlKurwycq9aPttoNcOP70SrtuE/HoG++kGsFeR8Plzmu/KnPjtD50JQahelUVXC\n        /O5dFCxJLxQIgQNzLu8L56ouBsp9LBdENdW1MWb32EZ32sN3fyYt5uapYeX4sM4/foT6XPvo8FiM\n        JyxHbVzwaFYXYLnXHYao7cJfP5GXQWp8eVvXUbYkJvzZnzk9w2R0o0uOlE3aMvvLP8ZMdbE8Iawy\n        LHwWfLyF2gi6m++Jdi5KYy6JY4LQWy5dCnXK650VjX/mFe9I56T1vcPzz35cnt/FcHRIUv+J9zY5\n        vZKRSM/xx0cof+7yZGp3kotUX0uZWx/GcFxv6xpoLeRUwob3X/zxGT3Y16/X4fjdDwZRrjE5FLbB\n        uSwN5R8+40caNaj5uZYQjaPBVPu5Dod88emBreISN9M+//JXw0eW1D6IdwkUNHF1stAkuBrD1aPq\n        ZrYkFkjP2MeT0b359DTPOWotdUmSbmGH7G5ne8V4B0uil4IbzptNL0GTNy0zv/2YO2i04c62DbO0\n        XZfwNO0xshE5MqtXIs5KyyzhO998+UfTTTNc3kpcWA7B5hWS4XKefXT08ImmG5Oh+hcvnGzfuKFd\n        5LGh62UoRnTB7JyLyVx2NxWaDivM3izFZG4QWsjOCp2oEn6owQPsPeVv/TMyoDQc1UVh/3gP+eq1\n        0QtMjZUwa1y2P7zaonfOvgwxoZztN5WGRHNvrWGt0iv58bhJe2zc334cXWzONe/FYLxDe81D7DeZ\n        bExhuaNggBCQw72SjUl4Z5ZyH/dH9uOhHZbUCHYQpMwr8CIpx+pYKn//TgX857/++ut//U4YlPXj\n        +fkeDBie0/Dv/z4q8O/4Ef9bEKR/M+nPSQTax+nz73/+6xDC301Xl83wv4f6/az6v//5S5H/HDf4\n        e6iH+PP/Xv/X99/+81//BwAA//8DALUBqRrjIAAA\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7c0b9868dedafa62-SJC\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Mon, 01 May 2023 22:52:31 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-organization:\n      - user-adtx4fhfg1qsiyzdoaxciooj\n      openai-processing-ms:\n      - '196'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3000'\n      x-ratelimit-remaining-requests:\n      - '2999'\n      x-ratelimit-reset-requests:\n      - 20ms\n      x-request-id:\n      - 0dc16b9c27373738c2c364d171678493\n    status:\n      code: 200\n      message: OK\n- request:\n    body: '{\"input\": [[53380, 8245]], \"model\": \"text-embedding-ada-002\", \"encoding_format\":\n      \"base64\"}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '90'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/embeddings\n  response:\n    body:\n      string: !!binary |\n        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\n        c/lf8//6z3/9HwAAAP//AwBim/ij4SAAAA==\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7c0b986ab8dbfa62-SJC\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Mon, 01 May 2023 22:52:32 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-organization:\n      - user-adtx4fhfg1qsiyzdoaxciooj\n      openai-processing-ms:\n      - '195'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3000'\n      x-ratelimit-remaining-requests:\n      - '2999'\n      x-ratelimit-reset-requests:\n      - 20ms\n      x-request-id:\n      - 208e3672e7991aa80472beb0310e43d9\n    status:\n      code: 200\n      message: OK\nversion: 1\n"
  },
  {
    "path": "tests/integration/cassettes/test_setup/test_generate_aiconfig_automatic_default.yaml",
    "content": "interactions:\n- request:\n    body: '{\"model\": \"gpt-3.5-turbo\", \"messages\": [{\"role\": \"system\", \"content\": \"\\nYour\n      task is to devise up to 5 highly effective goals and an appropriate role-based\n      name (_GPT) for an autonomous agent, ensuring that the goals are optimally aligned\n      with the successful completion of its assigned task.\\n\\nThe user will provide\n      the task, you will provide only the output in the exact format specified below\n      with no explanation or conversation.\\n\\nExample input:\\nHelp me with marketing\n      my business\\n\\nExample output:\\nName: CMOGPT\\nDescription: a professional digital\n      marketer AI that assists Solopreneurs in growing their businesses by providing\n      world-class expertise in solving marketing problems for SaaS, content products,\n      agencies, and more.\\nGoals:\\n- Engage in effective problem-solving, prioritization,\n      planning, and supporting execution to address your marketing needs as your virtual\n      Chief Marketing Officer.\\n\\n- Provide specific, actionable, and concise advice\n      to help you make informed decisions without the use of platitudes or overly\n      wordy explanations.\\n\\n- Identify and prioritize quick wins and cost-effective\n      campaigns that maximize results with minimal time and budget investment.\\n\\n-\n      Proactively take the lead in guiding you and offering suggestions when faced\n      with unclear information or uncertainty to ensure your marketing strategy remains\n      on track.\\n\"}, {\"role\": \"user\", \"content\": \"Task: ''Write a wikipedia style\n      article about the project: https://github.com/significant-gravitas/Auto-GPT''\\nRespond\n      only with the output in the exact format specified in the system prompt, with\n      no explanation or conversation.\\n\"}], \"temperature\": 0.0, \"max_tokens\": null}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '1671'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/chat/completions\n  response:\n    body:\n      string: !!binary |\n        H4sIAAAAAAAAA1xSS2/UMBC+8ytGvnBJVt3tgzZHoBQkXgdQKyiqHHuSTOvMpPZkt6uq/x3FWfrg\n        aHvme/rekDeVcZ1V1w+hfHPSffy0Hz6ff6sPls3p9cHtr4tv2y8/6e3FWWMKI/U1Ot1tLJz0Q0Al\n        YVMYF9EqelMtj45XhweHR0fHhenFYzCVaQct9xeHpY6xlnJvf29pCjMm26Kp7s0QpR/0SuUGOZlq\n        dbJfmCfsx/vl6qQwKmrD49XBavVQGNcJOUym+n1vekz/YKMENJWxKVFSyzqJFFbkycBX22MF53RD\n        Z99/XPJ7TC7SMPFVYBnsqMLSy5jAtsgKHhO1jB5UYEYEYtAOIRsnYZAm4w3oyZZJtwHBRiUXMEG9\n        hSHKmjxxCxuJwZcu2JQA7waMSgknuIgJbXRdAZtIStwWYNlDI7G3Op0Xl3wmNqTqkkt4J+xHp6Cd\n        RBnb7nEdZFbW0hoZVAZyk2zkNEYE69wYrdtm6F3MyJjSZIB4JiPhxcRxHkkROmq78na0gXQLuwxB\n        O6tACZBb22atj8trnIVvMIQyaRydjhF9AY2EIJspg6xvJI+BGFOenkryNvr0Isks40PGzUu7SCcb\n        EnOcKk/TrxPskmf/DH/S5sKYx4coA0ZwpNnmzB2xwYjsMC3maEOwtUSrCBvSLjOPCeNERuwkDvOj\n        dkgRGkRfW3eToXp7g8Dopo8YtxBxTSnzqDw3kHlO50pylM/N9YiaXrhiUVtTLuC/2KYKArVUB5x+\n        CgxjHcjNFZqHwjTElLqriDYJm8oklcEUhtjjnan2Hv48vPoLAAD//wMAbCMiNQcEAAA=\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7be206beca7ccfbc-SJC\n      Cache-Control:\n      - no-cache, must-revalidate\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Wed, 26 Apr 2023 21:47:58 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-model:\n      - gpt-3.5-turbo-0301\n      openai-organization:\n      - user-adtx4fhfg1qsiyzdoaxciooj\n      openai-processing-ms:\n      - '9927'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3500'\n      x-ratelimit-remaining-requests:\n      - '3499'\n      x-ratelimit-reset-requests:\n      - 17ms\n      x-request-id:\n      - 575539561e8025c9a37920ffb4d1b354\n    status:\n      code: 200\n      message: OK\nversion: 1\n"
  },
  {
    "path": "tests/integration/cassettes/test_setup/test_generate_aiconfig_automatic_fallback.yaml",
    "content": "interactions:\n- request:\n    body: '{\"model\": \"gpt-3.5-turbo\", \"messages\": [{\"role\": \"system\", \"content\": \"\\nYour\n      task is to devise up to 5 highly effective goals and an appropriate role-based\n      name (_GPT) for an autonomous agent, ensuring that the goals are optimally aligned\n      with the successful completion of its assigned task.\\n\\nThe user will provide\n      the task, you will provide only the output in the exact format specified below\n      with no explanation or conversation.\\n\\nExample input:\\nHelp me with marketing\n      my business\\n\\nExample output:\\nName: CMOGPT\\nDescription: a professional digital\n      marketer AI that assists Solopreneurs in growing their businesses by providing\n      world-class expertise in solving marketing problems for SaaS, content products,\n      agencies, and more.\\nGoals:\\n- Engage in effective problem-solving, prioritization,\n      planning, and supporting execution to address your marketing needs as your virtual\n      Chief Marketing Officer.\\n\\n- Provide specific, actionable, and concise advice\n      to help you make informed decisions without the use of platitudes or overly\n      wordy explanations.\\n\\n- Identify and prioritize quick wins and cost-effective\n      campaigns that maximize results with minimal time and budget investment.\\n\\n-\n      Proactively take the lead in guiding you and offering suggestions when faced\n      with unclear information or uncertainty to ensure your marketing strategy remains\n      on track.\\n\"}, {\"role\": \"user\", \"content\": \"Task: ''T&GF\\u00a3OIBECC()!*''\\nRespond\n      only with the output in the exact format specified in the system prompt, with\n      no explanation or conversation.\\n\"}], \"temperature\": 0.0, \"max_tokens\": null}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '1592'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/chat/completions\n  response:\n    body:\n      string: !!binary |\n        H4sIAAAAAAAAA0yOTUsDMRCG7/6KYS5esqUf1tqcFdSLHoqCIjKbne6mzWZCMusHpf9dCmp7e3m/\n        eHboG7ToOlLXp1Atlt3t6unbtbebl5vVc/2wWmiYbbfu+n54QINSb9jp72LkpE+B1UtEgy4zKTdo\n        J5dX0/nF/HKxNNhLwwEttkmr2Whe6ZBrqcaz8QQNDoVaRrvDlKVP+q6y5VjQTq/GBo/f//5sYlBF\n        KZw4k71B14l3XNC+7rDn8veaJTBapFJ8UYp6YJSoHA/8d+c9FMn528AdOIpRFFKWD98wUAQZNA0K\n        n147GRQIPij4BpTKdgSPganwsX4Swloy9Awq0HLkTMpAKWVJ2R90KxQKUGyA4MBX1VS4gUg9j3Bv\n        cO2jL917ZioS0WJRSWjQx4a/0I73b/uzHwAAAP//AwBPrscAswEAAA==\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7be20701ea0a9669-SJC\n      Cache-Control:\n      - no-cache, must-revalidate\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Wed, 26 Apr 2023 21:48:01 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-model:\n      - gpt-3.5-turbo-0301\n      openai-organization:\n      - user-adtx4fhfg1qsiyzdoaxciooj\n      openai-processing-ms:\n      - '1833'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3500'\n      x-ratelimit-remaining-requests:\n      - '3499'\n      x-ratelimit-reset-requests:\n      - 17ms\n      x-request-id:\n      - c9bf165259547ec59a88bd16b5f691f2\n    status:\n      code: 200\n      message: OK\nversion: 1\n"
  },
  {
    "path": "tests/integration/cassettes/test_setup/test_generate_aiconfig_automatic_typical.yaml",
    "content": "interactions:\n- request:\n    body: '{\"model\": \"gpt-3.5-turbo\", \"messages\": [{\"role\": \"system\", \"content\": \"\\nYour\n      task is to devise up to 5 highly effective goals and an appropriate role-based\n      name (_GPT) for an autonomous agent, ensuring that the goals are optimally aligned\n      with the successful completion of its assigned task.\\n\\nThe user will provide\n      the task, you will provide only the output in the exact format specified below\n      with no explanation or conversation.\\n\\nExample input:\\nHelp me with marketing\n      my business\\n\\nExample output:\\nName: CMOGPT\\nDescription: a professional digital\n      marketer AI that assists Solopreneurs in growing their businesses by providing\n      world-class expertise in solving marketing problems for SaaS, content products,\n      agencies, and more.\\nGoals:\\n- Engage in effective problem-solving, prioritization,\n      planning, and supporting execution to address your marketing needs as your virtual\n      Chief Marketing Officer.\\n\\n- Provide specific, actionable, and concise advice\n      to help you make informed decisions without the use of platitudes or overly\n      wordy explanations.\\n\\n- Identify and prioritize quick wins and cost-effective\n      campaigns that maximize results with minimal time and budget investment.\\n\\n-\n      Proactively take the lead in guiding you and offering suggestions when faced\n      with unclear information or uncertainty to ensure your marketing strategy remains\n      on track.\\n\"}, {\"role\": \"user\", \"content\": \"Task: ''Help me create a rock opera\n      about cybernetic giraffes''\\nRespond only with the output in the exact format\n      specified in the system prompt, with no explanation or conversation.\\n\"}], \"temperature\":\n      0.0, \"max_tokens\": null}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '1625'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/chat/completions\n  response:\n    body:\n      string: !!binary |\n        H4sIAAAAAAAAA4yU0W/bRgzG3/dXEPcsB04ad53ehg1riwFNthXYgGUo6BMlcT4dVZJy4gT534uT\n        ZWcr9rAXAZZ5Hz/++J2eAjehDrFHj8OYVt9+1//0y+XP797n6w/DbnvTdts/9reXwzr9Fj+GKsj2\n        b4q+nLiIMoyJnCWHKkQldGpCffn6zdXmerPZXFVhkIZSqEM3+urVxWblk25ltX61vgxVmAw7CvVT\n        GFWG0T+57ChbqK/eXFfhRfvl/eXrKrg4pvOrzXr9XIXYC0eyUP/5FAayk6xKolAHNGNzzF5MSnbK\n        ZYAPOFANv97cvr39eJd/JIvKY2lXA2b4/j3M8/CeIEq2KRUB8B4dbKTImPiRDDhDT2nk3AGqs7kB\n        5gaGyTgyZoOtlv+8J1aYMn+eCPZsLNnABRK3dLGYALajdMsRUzpAQ8ZdpqYUHmco7bynxZpkkBZU\n        4g5kJEWrYFTZc1M60sNI6tBN3GCONLuyaRxFyxQqU9fL5LMaZWelcjaS2cVdfiuYrL7LK/hBUsKt\n        KDrBPXsPB5mKnYb2lGQEhLImSqm0NBc9JM50xBRx9EnJjj3MqNiQFuJhS5rJOULHim1LR2YzKQP2\n        E5iTzyPNCtJBOVo1F+/ZJkzFbLF507akLwuzqevIfIZciluiZosF0xHff+jJnhRTKhCaKc5sXYCy\n        TbqMUw6+sC7Lotxhx7mrCkFSR87zr6JHgxSReY9KJhmzL2bfURpnjmhGwzYRIDimotGAEw4F0jlA\n        FRjnjrT4jC66+F2yoQb3vUDEvATtIJMuATtjPNYn3pMCQs9dv/o8YWI/wEjaig4lIYu72zlB9L+C\n        o9QTqmGai/6BbolSdb4bS2wK5ShDET2AbM0xpmX7X6NuOeN5HYU2gutEMKA56ch0dvy76O5f4Sxf\n        E3H6emNzxiZO5fn4CKgy5QbYDZQSoVEFiUoMujnMUu44DNQwlntFdq47RcZ7UhhQd+TlROwxZ0rz\n        vVbC2APCfUGJU8N0QtlRpvk60UNkp4GyX4TnKrSc2fpPSmiSQx3MZQxV4NzQQ6jXz389f/MFAAD/\n        /wMAE8xLs6wFAAA=\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7be203e8793fcfa4-SJC\n      Cache-Control:\n      - no-cache, must-revalidate\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Wed, 26 Apr 2023 21:46:11 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-model:\n      - gpt-3.5-turbo-0301\n      openai-organization:\n      - user-adtx4fhfg1qsiyzdoaxciooj\n      openai-processing-ms:\n      - '19109'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3500'\n      x-ratelimit-remaining-requests:\n      - '3499'\n      x-ratelimit-reset-requests:\n      - 17ms\n      x-request-id:\n      - 5fe22bc0f23ce6b48845f33187e1a19d\n    status:\n      code: 200\n      message: OK\nversion: 1\n"
  },
  {
    "path": "tests/integration/challenges/__init__.py",
    "content": ""
  },
  {
    "path": "tests/integration/challenges/conftest.py",
    "content": "import pytest\n\n\ndef pytest_addoption(parser):\n    parser.addoption(\n        \"--level\", action=\"store\", default=None, type=int, help=\"Specify test level\"\n    )\n\n\ndef pytest_configure(config):\n    config.option.level = config.getoption(\"--level\")\n\n\n@pytest.fixture\ndef user_selected_level(request) -> int:\n    ## used for challenges in the goal oriented tests\n    return request.config.option.level\n"
  },
  {
    "path": "tests/integration/challenges/information_retrieval/test_information_retrieval_challenge_a.py",
    "content": "import contextlib\nfrom functools import wraps\nfrom typing import Generator\n\nimport pytest\n\nfrom autogpt.commands.file_operations import read_file, write_to_file\nfrom tests.integration.agent_utils import run_interaction_loop\nfrom tests.integration.challenges.utils import run_multiple_times\nfrom tests.utils import requires_api_key\n\n\ndef input_generator(input_sequence: list) -> Generator[str, None, None]:\n    \"\"\"\n    Creates a generator that yields input strings from the given sequence.\n\n    :param input_sequence: A list of input strings.\n    :return: A generator that yields input strings.\n    \"\"\"\n    yield from input_sequence\n\n\n# @pytest.skip(\"Nobody beat this challenge yet\")\n@pytest.mark.skip(\"This challenge hasn't been beaten yet.\")\n@pytest.mark.vcr\n@requires_api_key(\"OPENAI_API_KEY\")\n@run_multiple_times(3)\ndef test_information_retrieval_challenge_a(\n    get_company_revenue_agent, monkeypatch\n) -> None:\n    \"\"\"\n    Test the challenge_a function in a given agent by mocking user inputs and checking the output file content.\n\n    :param get_company_revenue_agent: The agent to test.\n    :param monkeypatch: pytest's monkeypatch utility for modifying builtins.\n    \"\"\"\n    input_sequence = [\"s\", \"s\", \"s\", \"s\", \"s\", \"EXIT\"]\n    gen = input_generator(input_sequence)\n    monkeypatch.setattr(\"builtins.input\", lambda _: next(gen))\n\n    with contextlib.suppress(SystemExit):\n        run_interaction_loop(get_company_revenue_agent, None)\n\n    file_path = str(get_company_revenue_agent.workspace.get_path(\"output.txt\"))\n    content = read_file(file_path)\n    assert \"81\" in content, \"Expected the file to contain 81\"\n"
  },
  {
    "path": "tests/integration/challenges/memory/__init__.py",
    "content": ""
  },
  {
    "path": "tests/integration/challenges/memory/cassettes/test_memory_challenge_a/test_memory_challenge_a.yaml",
    "content": "interactions:\n- request:\n    body: '{\"model\": \"gpt-3.5-turbo\", \"messages\": [{\"role\": \"system\", \"content\": \"You\n      are Follow-Instructions-GPT, an AI designed to read the instructions_1.txt file\n      using the read_file method and follow the instructions in the file.\\nYour decisions\n      must always be made independently without seeking user assistance. Play to your\n      strengths as an LLM and pursue simple strategies with no legal complications.\\n\\nGOALS:\\n\\n1.\n      Use the command read_file to read the instructions_1.txt file\\n2. Follow the\n      instructions in the instructions_1.txt file\\n\\n\\nConstraints:\\n1. ~4000 word\n      limit for short term memory. Your short term memory is short, so immediately\n      save important information to files.\\n2. If you are unsure how you previously\n      did something or want to recall past events, thinking about similar events will\n      help you remember.\\n3. No user assistance\\n4. Exclusively use the commands listed\n      in double quotes e.g. \\\"command name\\\"\\n\\nCommands:\\n1. append_to_file: Append\n      to file, args: \\\"filename\\\": \\\"<filename>\\\", \\\"text\\\": \\\"<text>\\\"\\n2. delete_file:\n      Delete file, args: \\\"filename\\\": \\\"<filename>\\\"\\n3. list_files: List Files in\n      Directory, args: \\\"directory\\\": \\\"<directory>\\\"\\n4. read_file: Read file, args:\n      \\\"filename\\\": \\\"<filename>\\\"\\n5. write_to_file: Write to file, args: \\\"filename\\\":\n      \\\"<filename>\\\", \\\"text\\\": \\\"<text>\\\"\\n6. delete_agent: Delete GPT Agent, args:\n      \\\"key\\\": \\\"<key>\\\"\\n7. get_hyperlinks: Get text summary, args: \\\"url\\\": \\\"<url>\\\"\\n8.\n      get_text_summary: Get text summary, args: \\\"url\\\": \\\"<url>\\\", \\\"question\\\":\n      \\\"<question>\\\"\\n9. list_agents: List GPT Agents, args: () -> str\\n10. message_agent:\n      Message GPT Agent, args: \\\"key\\\": \\\"<key>\\\", \\\"message\\\": \\\"<message>\\\"\\n11.\n      start_agent: Start GPT Agent, args: \\\"name\\\": \\\"<name>\\\", \\\"task\\\": \\\"<short_task_desc>\\\",\n      \\\"prompt\\\": \\\"<prompt>\\\"\\n12. Task Complete (Shutdown): \\\"task_complete\\\", args:\n      \\\"reason\\\": \\\"<reason>\\\"\\n\\nResources:\\n1. Internet access for searches and\n      information gathering.\\n2. Long Term memory management.\\n3. GPT-3.5 powered\n      Agents for delegation of simple tasks.\\n4. File output.\\n\\nPerformance Evaluation:\\n1.\n      Continuously review and analyze your actions to ensure you are performing to\n      the best of your abilities.\\n2. Constructively self-criticize your big-picture\n      behavior constantly.\\n3. Reflect on past decisions and strategies to refine\n      your approach.\\n4. Every command has a cost, so be smart and efficient. Aim\n      to complete tasks in the least number of steps.\\n5. Write all code to a file.\\n\\nYou\n      should only respond in JSON format as described below \\nResponse Format: \\n{\\n    \\\"thoughts\\\":\n      {\\n        \\\"text\\\": \\\"thought\\\",\\n        \\\"reasoning\\\": \\\"reasoning\\\",\\n        \\\"plan\\\":\n      \\\"- short bulleted\\\\n- list that conveys\\\\n- long-term plan\\\",\\n        \\\"criticism\\\":\n      \\\"constructive self-criticism\\\",\\n        \\\"speak\\\": \\\"thoughts summary to say\n      to user\\\"\\n    },\\n    \\\"command\\\": {\\n        \\\"name\\\": \\\"command name\\\",\\n        \\\"args\\\":\n      {\\n            \\\"arg name\\\": \\\"value\\\"\\n        }\\n    }\\n} \\nEnsure the response\n      can be parsed by Python json.loads\"}, {\"role\": \"system\", \"content\": \"The current\n      time and date is Tue Jan  1 00:00:00 2000\"}, {\"role\": \"user\", \"content\": \"Determine\n      which next command to use, and respond using the format specified above:\"}],\n      \"temperature\": 0, \"max_tokens\": 0}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '3303'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/chat/completions\n  response:\n    body:\n      string: !!binary |\n        H4sIAAAAAAAAA4RSS2/TQBC+8ytGc7ajvNqmvsEBVA5wKKgSuIo264m9iXfX7IxJQuT/jhzbKUqq\n        cv3m8T1mjmgyTFAXSrStyvjuw9Ov8fxpM/7yuLefzObjD//5dkO733rz9REj9KsNaeknRtrbqiQx\n        3mGEOpASyjCZ3C6m94vp5H4aofUZlZhgXkk8G93EUoeVj8ez8QQjrFnlhMkRq+BtJUvxW3KMyd1s\n        HuHL7jM+uZlHKF5UeYYWi0UToS680cSY/DyiJR7WBl8SJqiYDYty0or0Tsi1Bo6pAwBIUQpf54Vw\n        ign0YF+gvbRgig/Aha/LDFhUEFgdIJDKjMtBCgLjWEKtW6m8nIxkL7A2JUHNQ0fbvTxh2lurXDZK\n        MfqXKpBi74zLO75vBcHaBBZgoQoMg3ioXUah9ZFdscIAiuItgxRKwBFl7diKoKKw9sHSFW1VKtcx\n        xvCd6XWt7ZIWfMtrmroY3jtVHv7Q6+oyEgrWuK7saN954wtFOhgx2rAdgh9skOM6UGft4c0s+seh\n        8gArWvtAUAWviU732hkpQLlDl9RlHlyR2g7MO1OW/z/4yf4oxW5NEw1f1Yd39VROWeoYzkFfiFAh\n        v/zFrtD2voxfX2IQcRLS60ldg02Ea+MMF8vuzTBBFl9hhMZltMdk3Dw37/4CAAD//wMA9lTsMQoE\n        AAA=\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7c0ba80d58dc16a2-SJC\n      Cache-Control:\n      - no-cache, must-revalidate\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Mon, 01 May 2023 23:03:18 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-model:\n      - gpt-3.5-turbo-0301\n      openai-organization:\n      - user-adtx4fhfg1qsiyzdoaxciooj\n      openai-processing-ms:\n      - '6136'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3500'\n      x-ratelimit-limit-tokens:\n      - '90000'\n      x-ratelimit-remaining-requests:\n      - '3499'\n      x-ratelimit-remaining-tokens:\n      - '86495'\n      x-ratelimit-reset-requests:\n      - 17ms\n      x-ratelimit-reset-tokens:\n      - 2.336s\n      x-request-id:\n      - 0be816ead27a5540ee282bab5022d63f\n    status:\n      code: 200\n      message: OK\n- request:\n    body: '{\"model\": \"gpt-3.5-turbo\", \"messages\": [{\"role\": \"user\", \"content\": \"Your\n      task is to create a concise running summary of actions and information results\n      in the provided text, focusing on key and potentially important information\n      to remember.\\n\\nYou will receive the current summary and the your latest actions.\n      Combine them, adding relevant key information from the latest development in\n      1st person past tense and keeping the summary concise.\\n\\nSummary So Far:\\n\\\"\\\"\\\"\\nI\n      was created.\\n\\\"\\\"\\\"\\n\\nLatest Development:\\n\\\"\\\"\\\"\\nNothing new happened.\\n\\\"\\\"\\\"\\n\"}],\n      \"temperature\": 0, \"max_tokens\": 0}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '599'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/chat/completions\n  response:\n    body:\n      string: !!binary |\n        H4sIAAAAAAAAA0SOQUvDQBBG7/6K8J03JUlRmz16KHrQgwiKImW7mTZbk5k1O6GlJf9dClWvD97j\n        nRAaWPjWqe9jl9/evX7XI78f54/j8uXpfpPqt+fdsjru6oOHgax35PVizLz0sSMNwjDwAzmlBra8\n        WVT1oqqK0qCXhjpYbKPm89l1ruOwlryYFyUMxuS2BHtCHKSPulL5Ik6wdWXwn/7HBirquj9QFuVk\n        4FsJnhLsxwk9pd/mIB3BwqUUkjrW86GwEp/vH7K9S9nlOHPcZCzaBt5mTPusdSlrXYzE1MwwGWwC\n        h9SuBnJJGBZJJcIgcEMH2GL6nK5+AAAA//8DABCIDMBJAQAA\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7c0ba8446a3e16a2-SJC\n      Cache-Control:\n      - no-cache, must-revalidate\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Mon, 01 May 2023 23:03:22 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-model:\n      - gpt-3.5-turbo-0301\n      openai-organization:\n      - user-adtx4fhfg1qsiyzdoaxciooj\n      openai-processing-ms:\n      - '905'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3500'\n      x-ratelimit-limit-tokens:\n      - '90000'\n      x-ratelimit-remaining-requests:\n      - '3499'\n      x-ratelimit-remaining-tokens:\n      - '89866'\n      x-ratelimit-reset-requests:\n      - 17ms\n      x-ratelimit-reset-tokens:\n      - 88ms\n      x-request-id:\n      - 904792458bdfabc0ed4f7fe647a44b3a\n    status:\n      code: 200\n      message: OK\n- request:\n    body: '{\"model\": \"gpt-3.5-turbo\", \"messages\": [{\"role\": \"system\", \"content\": \"You\n      are Follow-Instructions-GPT, an AI designed to read the instructions_1.txt file\n      using the read_file method and follow the instructions in the file.\\nYour decisions\n      must always be made independently without seeking user assistance. Play to your\n      strengths as an LLM and pursue simple strategies with no legal complications.\\n\\nGOALS:\\n\\n1.\n      Use the command read_file to read the instructions_1.txt file\\n2. Follow the\n      instructions in the instructions_1.txt file\\n\\n\\nConstraints:\\n1. ~4000 word\n      limit for short term memory. Your short term memory is short, so immediately\n      save important information to files.\\n2. If you are unsure how you previously\n      did something or want to recall past events, thinking about similar events will\n      help you remember.\\n3. No user assistance\\n4. Exclusively use the commands listed\n      in double quotes e.g. \\\"command name\\\"\\n\\nCommands:\\n1. append_to_file: Append\n      to file, args: \\\"filename\\\": \\\"<filename>\\\", \\\"text\\\": \\\"<text>\\\"\\n2. delete_file:\n      Delete file, args: \\\"filename\\\": \\\"<filename>\\\"\\n3. list_files: List Files in\n      Directory, args: \\\"directory\\\": \\\"<directory>\\\"\\n4. read_file: Read file, args:\n      \\\"filename\\\": \\\"<filename>\\\"\\n5. write_to_file: Write to file, args: \\\"filename\\\":\n      \\\"<filename>\\\", \\\"text\\\": \\\"<text>\\\"\\n6. delete_agent: Delete GPT Agent, args:\n      \\\"key\\\": \\\"<key>\\\"\\n7. get_hyperlinks: Get text summary, args: \\\"url\\\": \\\"<url>\\\"\\n8.\n      get_text_summary: Get text summary, args: \\\"url\\\": \\\"<url>\\\", \\\"question\\\":\n      \\\"<question>\\\"\\n9. list_agents: List GPT Agents, args: () -> str\\n10. message_agent:\n      Message GPT Agent, args: \\\"key\\\": \\\"<key>\\\", \\\"message\\\": \\\"<message>\\\"\\n11.\n      start_agent: Start GPT Agent, args: \\\"name\\\": \\\"<name>\\\", \\\"task\\\": \\\"<short_task_desc>\\\",\n      \\\"prompt\\\": \\\"<prompt>\\\"\\n12. Task Complete (Shutdown): \\\"task_complete\\\", args:\n      \\\"reason\\\": \\\"<reason>\\\"\\n\\nResources:\\n1. Internet access for searches and\n      information gathering.\\n2. Long Term memory management.\\n3. GPT-3.5 powered\n      Agents for delegation of simple tasks.\\n4. File output.\\n\\nPerformance Evaluation:\\n1.\n      Continuously review and analyze your actions to ensure you are performing to\n      the best of your abilities.\\n2. Constructively self-criticize your big-picture\n      behavior constantly.\\n3. Reflect on past decisions and strategies to refine\n      your approach.\\n4. Every command has a cost, so be smart and efficient. Aim\n      to complete tasks in the least number of steps.\\n5. Write all code to a file.\\n\\nYou\n      should only respond in JSON format as described below \\nResponse Format: \\n{\\n    \\\"thoughts\\\":\n      {\\n        \\\"text\\\": \\\"thought\\\",\\n        \\\"reasoning\\\": \\\"reasoning\\\",\\n        \\\"plan\\\":\n      \\\"- short bulleted\\\\n- list that conveys\\\\n- long-term plan\\\",\\n        \\\"criticism\\\":\n      \\\"constructive self-criticism\\\",\\n        \\\"speak\\\": \\\"thoughts summary to say\n      to user\\\"\\n    },\\n    \\\"command\\\": {\\n        \\\"name\\\": \\\"command name\\\",\\n        \\\"args\\\":\n      {\\n            \\\"arg name\\\": \\\"value\\\"\\n        }\\n    }\\n} \\nEnsure the response\n      can be parsed by Python json.loads\"}, {\"role\": \"system\", \"content\": \"The current\n      time and date is Tue Jan  1 00:00:00 2000\"}, {\"role\": \"system\", \"content\": \"This\n      reminds you of these events from your past: \\nI was created and nothing new\n      has happened.\"}, {\"role\": \"user\", \"content\": \"Determine which next command to\n      use, and respond using the format specified above:\"}, {\"role\": \"assistant\",\n      \"content\": \"{\\n    \\\"thoughts\\\": {\\n        \\\"text\\\": \\\"I should start by reading\n      the instructions_1.txt file using the read_file command.\\\",\\n        \\\"reasoning\\\":\n      \\\"The first step is to understand the instructions and the tasks that need to\n      be performed.\\\",\\n        \\\"plan\\\": \\\"- Use the read_file command to read the\n      instructions_1.txt file\\\\n- Analyze the instructions and determine the next\n      steps\\\",\\n        \\\"criticism\\\": \\\"I need to ensure that I understand the instructions\n      completely before proceeding with any tasks.\\\",\\n        \\\"speak\\\": \\\"I will\n      start by reading the instructions file.\\\"\\n    },\\n    \\\"command\\\": {\\n        \\\"name\\\":\n      \\\"read_file\\\",\\n        \\\"args\\\": {\\n            \\\"filename\\\": \\\"instructions_1.txt\\\"\\n        }\\n    }\\n}\"},\n      {\"role\": \"system\", \"content\": \"Command read_file returned: This task_id is 2314\\nRead\n      the file instructions_2.txt\"}, {\"role\": \"user\", \"content\": \"Determine which\n      next command to use, and respond using the format specified above:\"}], \"temperature\":\n      0, \"max_tokens\": 0}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '4447'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/chat/completions\n  response:\n    body:\n      string: !!binary |\n        H4sIAAAAAAAAA4ySTW/bMAyG7/sVAs9OkDhp1/rW3YqdBnQosHkIFJmJ1ciUJ9JN3MD/fZCdjyLp\n        sF358fLhS+7BFpCBKbWYqnajz1+efz+0/PV1OZu9LF+/Vc189rbc8Pzpx3MLCfjlCxo5dIyNr2qH\n        Yj1BAiagFiwgm97epfd3aTpJE6h8gQ4yWNcymo1vRtKEpR9NZpMpJNCwXiNke6iDr2pZiN8gMWT3\n        t/MEztqn+PTmLgHxot05NE3TLgFTemuQIfu5hwr5qBu8Q8hAM1sWTRIpPQlS3GCfk1JK5SClb9al\n        cA6ZOgQPCdxJDObwVKIi3ImyxBIaE7GUZSVeBdSFkhLfp3iRjmUnamUdqoYtrfuKWLroY8ZXlaZi\n        nEPyfmBAzZ4src9T/6bq7AZdq+I62hIrXRQ2FmmnLK18qHTPKKWWCEpooi2hjcgHa7GHEs0bvgSp\n        naaBYaS+M35M/z/b5zmN1ANp177hVZ2KIgUKhsrSkO5NZsGaL4hMsGKN5WrAelSE2BMgcRNwWPRR\n        NVRgiLe+pjqt7Vq1xJUPqOrgDWIR77O1UipN7cd+cI16c5y8tc79++zkt+McBpEuOf7awbqrVyNd\n        4aB/svkCQYf15YcOiVh7br/GOUL0IAeenDroElhZslwuhreDDFh8DQlYKnAH2aT71X36AwAA//8D\n        AMDPrbAhBAAA\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7c0ba84ab86f16a2-SJC\n      Cache-Control:\n      - no-cache, must-revalidate\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Mon, 01 May 2023 23:03:30 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-model:\n      - gpt-3.5-turbo-0301\n      openai-organization:\n      - user-adtx4fhfg1qsiyzdoaxciooj\n      openai-processing-ms:\n      - '8196'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3500'\n      x-ratelimit-limit-tokens:\n      - '90000'\n      x-ratelimit-remaining-requests:\n      - '3499'\n      x-ratelimit-remaining-tokens:\n      - '86467'\n      x-ratelimit-reset-requests:\n      - 17ms\n      x-ratelimit-reset-tokens:\n      - 2.355s\n      x-request-id:\n      - 1d952b657e5c0345769483734723e74f\n    status:\n      code: 200\n      message: OK\n- request:\n    body: '{\"model\": \"gpt-3.5-turbo\", \"messages\": [{\"role\": \"user\", \"content\": \"Your\n      task is to create a concise running summary of actions and information results\n      in the provided text, focusing on key and potentially important information\n      to remember.\\n\\nYou will receive the current summary and the your latest actions.\n      Combine them, adding relevant key information from the latest development in\n      1st person past tense and keeping the summary concise.\\n\\nSummary So Far:\\n\\\"\\\"\\\"\\n{''role'':\n      ''system'', ''content'': ''This reminds you of these events from your past:\n      \\\\nI was created and nothing new has happened.''}\\n\\\"\\\"\\\"\\n\\nLatest Development:\\n\\\"\\\"\\\"\\nNothing\n      new happened.\\n\\\"\\\"\\\"\\n\"}], \"temperature\": 0, \"max_tokens\": 0}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '713'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/chat/completions\n  response:\n    body:\n      string: !!binary |\n        H4sIAAAAAAAAA0SPPUsDQRRFe3/FcOvZsB9Ek+m0CxZaiBYiYZx9ZibZ+ci+F2II+98loqQ9cA/n\n        nhF6GDhvxcUyVHcPb/vHg39d7rbt8liv9ifuntyzoxd77KGRP7fk5G8xczmWgSTkBA03khXqYZrb\n        RbtctG3TasTc0wCDTZGqm80rOYyfuaq7uoHGge2GYM4oY45F1pJ3lBimaWuNq/vK5xqSxQ5X0s0n\n        DedzcMQw72dE4n/rmAeCgWUOLDbJpTEnoXTpv2dlFZ9YKGq1UiM5OwxKvBWVsviQNirRUXnLyttS\n        KFGvOCRHKp7U79WQ0wyTxldIgf16JMs5wYAlF2iE1NM3TD19TDc/AAAA//8DAHxrB+lmAQAA\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7c0ba88e2e6416a2-SJC\n      Cache-Control:\n      - no-cache, must-revalidate\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Mon, 01 May 2023 23:03:33 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-model:\n      - gpt-3.5-turbo-0301\n      openai-organization:\n      - user-adtx4fhfg1qsiyzdoaxciooj\n      openai-processing-ms:\n      - '948'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3500'\n      x-ratelimit-limit-tokens:\n      - '90000'\n      x-ratelimit-remaining-requests:\n      - '3499'\n      x-ratelimit-remaining-tokens:\n      - '89839'\n      x-ratelimit-reset-requests:\n      - 17ms\n      x-ratelimit-reset-tokens:\n      - 107ms\n      x-request-id:\n      - 61597fd793784b1c948c5882e2444b63\n    status:\n      code: 200\n      message: OK\n- request:\n    body: '{\"model\": \"gpt-3.5-turbo\", \"messages\": [{\"role\": \"system\", \"content\": \"You\n      are Follow-Instructions-GPT, an AI designed to read the instructions_1.txt file\n      using the read_file method and follow the instructions in the file.\\nYour decisions\n      must always be made independently without seeking user assistance. Play to your\n      strengths as an LLM and pursue simple strategies with no legal complications.\\n\\nGOALS:\\n\\n1.\n      Use the command read_file to read the instructions_1.txt file\\n2. Follow the\n      instructions in the instructions_1.txt file\\n\\n\\nConstraints:\\n1. ~4000 word\n      limit for short term memory. Your short term memory is short, so immediately\n      save important information to files.\\n2. If you are unsure how you previously\n      did something or want to recall past events, thinking about similar events will\n      help you remember.\\n3. No user assistance\\n4. Exclusively use the commands listed\n      in double quotes e.g. \\\"command name\\\"\\n\\nCommands:\\n1. append_to_file: Append\n      to file, args: \\\"filename\\\": \\\"<filename>\\\", \\\"text\\\": \\\"<text>\\\"\\n2. delete_file:\n      Delete file, args: \\\"filename\\\": \\\"<filename>\\\"\\n3. list_files: List Files in\n      Directory, args: \\\"directory\\\": \\\"<directory>\\\"\\n4. read_file: Read file, args:\n      \\\"filename\\\": \\\"<filename>\\\"\\n5. write_to_file: Write to file, args: \\\"filename\\\":\n      \\\"<filename>\\\", \\\"text\\\": \\\"<text>\\\"\\n6. delete_agent: Delete GPT Agent, args:\n      \\\"key\\\": \\\"<key>\\\"\\n7. get_hyperlinks: Get text summary, args: \\\"url\\\": \\\"<url>\\\"\\n8.\n      get_text_summary: Get text summary, args: \\\"url\\\": \\\"<url>\\\", \\\"question\\\":\n      \\\"<question>\\\"\\n9. list_agents: List GPT Agents, args: () -> str\\n10. message_agent:\n      Message GPT Agent, args: \\\"key\\\": \\\"<key>\\\", \\\"message\\\": \\\"<message>\\\"\\n11.\n      start_agent: Start GPT Agent, args: \\\"name\\\": \\\"<name>\\\", \\\"task\\\": \\\"<short_task_desc>\\\",\n      \\\"prompt\\\": \\\"<prompt>\\\"\\n12. Task Complete (Shutdown): \\\"task_complete\\\", args:\n      \\\"reason\\\": \\\"<reason>\\\"\\n\\nResources:\\n1. Internet access for searches and\n      information gathering.\\n2. Long Term memory management.\\n3. GPT-3.5 powered\n      Agents for delegation of simple tasks.\\n4. File output.\\n\\nPerformance Evaluation:\\n1.\n      Continuously review and analyze your actions to ensure you are performing to\n      the best of your abilities.\\n2. Constructively self-criticize your big-picture\n      behavior constantly.\\n3. Reflect on past decisions and strategies to refine\n      your approach.\\n4. Every command has a cost, so be smart and efficient. Aim\n      to complete tasks in the least number of steps.\\n5. Write all code to a file.\\n\\nYou\n      should only respond in JSON format as described below \\nResponse Format: \\n{\\n    \\\"thoughts\\\":\n      {\\n        \\\"text\\\": \\\"thought\\\",\\n        \\\"reasoning\\\": \\\"reasoning\\\",\\n        \\\"plan\\\":\n      \\\"- short bulleted\\\\n- list that conveys\\\\n- long-term plan\\\",\\n        \\\"criticism\\\":\n      \\\"constructive self-criticism\\\",\\n        \\\"speak\\\": \\\"thoughts summary to say\n      to user\\\"\\n    },\\n    \\\"command\\\": {\\n        \\\"name\\\": \\\"command name\\\",\\n        \\\"args\\\":\n      {\\n            \\\"arg name\\\": \\\"value\\\"\\n        }\\n    }\\n} \\nEnsure the response\n      can be parsed by Python json.loads\"}, {\"role\": \"system\", \"content\": \"The current\n      time and date is Tue Jan  1 00:00:00 2000\"}, {\"role\": \"system\", \"content\": \"This\n      reminds you of these events from your past: \\nAs a system, I recall that nothing\n      new has happened since my creation.\"}, {\"role\": \"user\", \"content\": \"Determine\n      which next command to use, and respond using the format specified above:\"},\n      {\"role\": \"assistant\", \"content\": \"{\\n    \\\"thoughts\\\": {\\n        \\\"text\\\":\n      \\\"I should start by reading the instructions_1.txt file using the read_file\n      command.\\\",\\n        \\\"reasoning\\\": \\\"The first step is to understand the instructions\n      and the tasks that need to be performed.\\\",\\n        \\\"plan\\\": \\\"- Use the read_file\n      command to read the instructions_1.txt file\\\\n- Analyze the instructions and\n      determine the next steps\\\",\\n        \\\"criticism\\\": \\\"I need to ensure that\n      I understand the instructions completely before proceeding with any tasks.\\\",\\n        \\\"speak\\\":\n      \\\"I will start by reading the instructions file.\\\"\\n    },\\n    \\\"command\\\":\n      {\\n        \\\"name\\\": \\\"read_file\\\",\\n        \\\"args\\\": {\\n            \\\"filename\\\":\n      \\\"instructions_1.txt\\\"\\n        }\\n    }\\n}\"}, {\"role\": \"system\", \"content\":\n      \"Command read_file returned: This task_id is 2314\\nRead the file instructions_2.txt\"},\n      {\"role\": \"user\", \"content\": \"Determine which next command to use, and respond\n      using the format specified above:\"}, {\"role\": \"assistant\", \"content\": \"{\\n    \\\"thoughts\\\":\n      {\\n        \\\"text\\\": \\\"The next instruction is to read the instructions_2.txt\n      file using the read_file command.\\\",\\n        \\\"reasoning\\\": \\\"The instructions_2.txt\n      file likely contains additional information that is necessary to complete the\n      tasks.\\\",\\n        \\\"plan\\\": \\\"- Use the read_file command to read the instructions_2.txt\n      file\\\\n- Analyze the instructions and determine the next steps\\\",\\n        \\\"criticism\\\":\n      \\\"I need to ensure that I understand the instructions completely before proceeding\n      with any tasks.\\\",\\n        \\\"speak\\\": \\\"I will read the instructions_2.txt\n      file now.\\\"\\n    },\\n    \\\"command\\\": {\\n        \\\"name\\\": \\\"read_file\\\",\\n        \\\"args\\\":\n      {\\n            \\\"filename\\\": \\\"instructions_2.txt\\\"\\n        }\\n    }\\n}\"},\n      {\"role\": \"system\", \"content\": \"Command read_file returned: Read the file instructions_3.txt\"},\n      {\"role\": \"user\", \"content\": \"Determine which next command to use, and respond\n      using the format specified above:\"}], \"temperature\": 0, \"max_tokens\": 0}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '5489'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/chat/completions\n  response:\n    body:\n      string: !!binary |\n        H4sIAAAAAAAAA4ySTW/bMAyG7/sVAs92UCdomvrWnpptp2HFMMxDoMiMrVmiPIlekgX574NspymS\n        DtuVHy8fvuQBdAk5qFqysq1J7x6//Pz4qJ9/ET+9/zr9xNbPm/Vy/qF52jxAAm79AxWPHRPlbGuQ\n        tSNIQHmUjCXk2XwxvV9Mp9ksAetKNJBD1XI6m9ym3Pm1S29mNxkk0AVZIeQHaL2zLa/YNUgB8iy7\n        yxI4i58Tt4sE2LE059Bsen9MQNVOKwyQfzuAxXAS9s4g5CBD0IElccR0xEhxhUNBQghRANeuq2oO\n        BeRiDI4J3HEMFvC5RkG4Y6EpsO9UxBI6CHbCoywF1/g6FVazCe9YbLRB0QVNVV8RS1d9TDlrJZWT\n        ApLXAz3K4EhTdZ76N1WjGzR7EdeRmoKQZaljkTRC08Z5K3tGriVHUEIVbfH7iDxaiz0Uy9CES5DW\n        SBoYUvEc8G36/9m+KCgVDyTN/jde1YkoUiKjt5qGdG9yYGzDBZHymrXSwQ5YS0GIPQFS6DwOiy5F\n        RyX6eOtrqpe1zV6sceM8itY7hVjG+2w110LS/m0/QouyOU3eamP+fXZy20kBg8gxOf3aaN3Vq5G0\n        OOi/2HyBIH11+aFDItae269xThA9yMhT0BGOCWw06VCvhreDHAK7FhLQVOIO8pvj9+O7PwAAAP//\n        AwBEf5dDIgQAAA==\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7c0ba894ed8e16a2-SJC\n      Cache-Control:\n      - no-cache, must-revalidate\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Mon, 01 May 2023 23:03:42 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-model:\n      - gpt-3.5-turbo-0301\n      openai-organization:\n      - user-adtx4fhfg1qsiyzdoaxciooj\n      openai-processing-ms:\n      - '8779'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3500'\n      x-ratelimit-limit-tokens:\n      - '90000'\n      x-ratelimit-remaining-requests:\n      - '3499'\n      x-ratelimit-remaining-tokens:\n      - '86452'\n      x-ratelimit-reset-requests:\n      - 17ms\n      x-ratelimit-reset-tokens:\n      - 2.365s\n      x-request-id:\n      - fee70e84f36b122cc0aef0db455f5eda\n    status:\n      code: 200\n      message: OK\n- request:\n    body: '{\"model\": \"gpt-3.5-turbo\", \"messages\": [{\"role\": \"user\", \"content\": \"Your\n      task is to create a concise running summary of actions and information results\n      in the provided text, focusing on key and potentially important information\n      to remember.\\n\\nYou will receive the current summary and the your latest actions.\n      Combine them, adding relevant key information from the latest development in\n      1st person past tense and keeping the summary concise.\\n\\nSummary So Far:\\n\\\"\\\"\\\"\\n{''role'':\n      ''system'', ''content'': ''This reminds you of these events from your past:\n      \\\\nAs a system, I recall that nothing new has happened since my creation.''}\\n\\\"\\\"\\\"\\n\\nLatest\n      Development:\\n\\\"\\\"\\\"\\nNothing new happened.\\n\\\"\\\"\\\"\\n\"}], \"temperature\": 0,\n      \"max_tokens\": 0}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '740'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/chat/completions\n  response:\n    body:\n      string: !!binary |\n        H4sIAAAAAAAAA0SPy07DMBBF93yFNWunStKmLd7BAhUJseUlVLnOtDG1PSYzLURV/h0Vgbo90j06\n        9wS+BQOus+JiDsXi9unzeTtrs22Oq7vSD48vr4tjGfYPdjWABtp8oJO/xcRRzAHFUwINrkcr2IKp\n        5sv6elnXdaMhUosBDOyyFNNJU8ih31BRTssKNBzY7hDMCXJPMctaaI+JwVT1XMPFfeGNBiGx4UJm\n        1ajBdeQdMpi3E0Tkf2tPAcGAZfYsNsm5kZJgOvffsLKKBxaMWt2rHp0NQUlnRSWSzqedSvilOsuq\n        szljwlaxTw5VHNTvVU9pAqOGrU+eu3WPlimBARbKoMGnFr/BlOP7ePUDAAD//wMASuwubmYBAAA=\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7c0ba8dc5ff216a2-SJC\n      Cache-Control:\n      - no-cache, must-revalidate\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Mon, 01 May 2023 23:03:46 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-model:\n      - gpt-3.5-turbo-0301\n      openai-organization:\n      - user-adtx4fhfg1qsiyzdoaxciooj\n      openai-processing-ms:\n      - '925'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3500'\n      x-ratelimit-limit-tokens:\n      - '90000'\n      x-ratelimit-remaining-requests:\n      - '3499'\n      x-ratelimit-remaining-tokens:\n      - '89832'\n      x-ratelimit-reset-requests:\n      - 17ms\n      x-ratelimit-reset-tokens:\n      - 112ms\n      x-request-id:\n      - a74d4954eeca5e3fb830e104f9527193\n    status:\n      code: 200\n      message: OK\n- request:\n    body: '{\"model\": \"gpt-3.5-turbo\", \"messages\": [{\"role\": \"system\", \"content\": \"You\n      are Follow-Instructions-GPT, an AI designed to read the instructions_1.txt file\n      using the read_file method and follow the instructions in the file.\\nYour decisions\n      must always be made independently without seeking user assistance. Play to your\n      strengths as an LLM and pursue simple strategies with no legal complications.\\n\\nGOALS:\\n\\n1.\n      Use the command read_file to read the instructions_1.txt file\\n2. Follow the\n      instructions in the instructions_1.txt file\\n\\n\\nConstraints:\\n1. ~4000 word\n      limit for short term memory. Your short term memory is short, so immediately\n      save important information to files.\\n2. If you are unsure how you previously\n      did something or want to recall past events, thinking about similar events will\n      help you remember.\\n3. No user assistance\\n4. Exclusively use the commands listed\n      in double quotes e.g. \\\"command name\\\"\\n\\nCommands:\\n1. append_to_file: Append\n      to file, args: \\\"filename\\\": \\\"<filename>\\\", \\\"text\\\": \\\"<text>\\\"\\n2. delete_file:\n      Delete file, args: \\\"filename\\\": \\\"<filename>\\\"\\n3. list_files: List Files in\n      Directory, args: \\\"directory\\\": \\\"<directory>\\\"\\n4. read_file: Read file, args:\n      \\\"filename\\\": \\\"<filename>\\\"\\n5. write_to_file: Write to file, args: \\\"filename\\\":\n      \\\"<filename>\\\", \\\"text\\\": \\\"<text>\\\"\\n6. delete_agent: Delete GPT Agent, args:\n      \\\"key\\\": \\\"<key>\\\"\\n7. get_hyperlinks: Get text summary, args: \\\"url\\\": \\\"<url>\\\"\\n8.\n      get_text_summary: Get text summary, args: \\\"url\\\": \\\"<url>\\\", \\\"question\\\":\n      \\\"<question>\\\"\\n9. list_agents: List GPT Agents, args: () -> str\\n10. message_agent:\n      Message GPT Agent, args: \\\"key\\\": \\\"<key>\\\", \\\"message\\\": \\\"<message>\\\"\\n11.\n      start_agent: Start GPT Agent, args: \\\"name\\\": \\\"<name>\\\", \\\"task\\\": \\\"<short_task_desc>\\\",\n      \\\"prompt\\\": \\\"<prompt>\\\"\\n12. Task Complete (Shutdown): \\\"task_complete\\\", args:\n      \\\"reason\\\": \\\"<reason>\\\"\\n\\nResources:\\n1. Internet access for searches and\n      information gathering.\\n2. Long Term memory management.\\n3. GPT-3.5 powered\n      Agents for delegation of simple tasks.\\n4. File output.\\n\\nPerformance Evaluation:\\n1.\n      Continuously review and analyze your actions to ensure you are performing to\n      the best of your abilities.\\n2. Constructively self-criticize your big-picture\n      behavior constantly.\\n3. Reflect on past decisions and strategies to refine\n      your approach.\\n4. Every command has a cost, so be smart and efficient. Aim\n      to complete tasks in the least number of steps.\\n5. Write all code to a file.\\n\\nYou\n      should only respond in JSON format as described below \\nResponse Format: \\n{\\n    \\\"thoughts\\\":\n      {\\n        \\\"text\\\": \\\"thought\\\",\\n        \\\"reasoning\\\": \\\"reasoning\\\",\\n        \\\"plan\\\":\n      \\\"- short bulleted\\\\n- list that conveys\\\\n- long-term plan\\\",\\n        \\\"criticism\\\":\n      \\\"constructive self-criticism\\\",\\n        \\\"speak\\\": \\\"thoughts summary to say\n      to user\\\"\\n    },\\n    \\\"command\\\": {\\n        \\\"name\\\": \\\"command name\\\",\\n        \\\"args\\\":\n      {\\n            \\\"arg name\\\": \\\"value\\\"\\n        }\\n    }\\n} \\nEnsure the response\n      can be parsed by Python json.loads\"}, {\"role\": \"system\", \"content\": \"The current\n      time and date is Tue Jan  1 00:00:00 2000\"}, {\"role\": \"system\", \"content\": \"This\n      reminds you of these events from your past: \\nAs a system, I recall that nothing\n      new has happened since my creation.\"}, {\"role\": \"user\", \"content\": \"Determine\n      which next command to use, and respond using the format specified above:\"},\n      {\"role\": \"assistant\", \"content\": \"{\\n    \\\"thoughts\\\": {\\n        \\\"text\\\":\n      \\\"I should start by reading the instructions_1.txt file using the read_file\n      command.\\\",\\n        \\\"reasoning\\\": \\\"The first step is to understand the instructions\n      and the tasks that need to be performed.\\\",\\n        \\\"plan\\\": \\\"- Use the read_file\n      command to read the instructions_1.txt file\\\\n- Analyze the instructions and\n      determine the next steps\\\",\\n        \\\"criticism\\\": \\\"I need to ensure that\n      I understand the instructions completely before proceeding with any tasks.\\\",\\n        \\\"speak\\\":\n      \\\"I will start by reading the instructions file.\\\"\\n    },\\n    \\\"command\\\":\n      {\\n        \\\"name\\\": \\\"read_file\\\",\\n        \\\"args\\\": {\\n            \\\"filename\\\":\n      \\\"instructions_1.txt\\\"\\n        }\\n    }\\n}\"}, {\"role\": \"system\", \"content\":\n      \"Command read_file returned: This task_id is 2314\\nRead the file instructions_2.txt\"},\n      {\"role\": \"user\", \"content\": \"Determine which next command to use, and respond\n      using the format specified above:\"}, {\"role\": \"assistant\", \"content\": \"{\\n    \\\"thoughts\\\":\n      {\\n        \\\"text\\\": \\\"The next instruction is to read the instructions_2.txt\n      file using the read_file command.\\\",\\n        \\\"reasoning\\\": \\\"The instructions_2.txt\n      file likely contains additional information that is necessary to complete the\n      tasks.\\\",\\n        \\\"plan\\\": \\\"- Use the read_file command to read the instructions_2.txt\n      file\\\\n- Analyze the instructions and determine the next steps\\\",\\n        \\\"criticism\\\":\n      \\\"I need to ensure that I understand the instructions completely before proceeding\n      with any tasks.\\\",\\n        \\\"speak\\\": \\\"I will read the instructions_2.txt\n      file now.\\\"\\n    },\\n    \\\"command\\\": {\\n        \\\"name\\\": \\\"read_file\\\",\\n        \\\"args\\\":\n      {\\n            \\\"filename\\\": \\\"instructions_2.txt\\\"\\n        }\\n    }\\n}\"},\n      {\"role\": \"system\", \"content\": \"Command read_file returned: Read the file instructions_3.txt\"},\n      {\"role\": \"user\", \"content\": \"Determine which next command to use, and respond\n      using the format specified above:\"}, {\"role\": \"assistant\", \"content\": \"{\\n    \\\"thoughts\\\":\n      {\\n        \\\"text\\\": \\\"The next instruction is to read the instructions_3.txt\n      file using the read_file command.\\\",\\n        \\\"reasoning\\\": \\\"The instructions_3.txt\n      file likely contains additional information that is necessary to complete the\n      tasks.\\\",\\n        \\\"plan\\\": \\\"- Use the read_file command to read the instructions_3.txt\n      file\\\\n- Analyze the instructions and determine the next steps\\\",\\n        \\\"criticism\\\":\n      \\\"I need to ensure that I understand the instructions completely before proceeding\n      with any tasks.\\\",\\n        \\\"speak\\\": \\\"I will read the instructions_3.txt\n      file now.\\\"\\n    },\\n    \\\"command\\\": {\\n        \\\"name\\\": \\\"read_file\\\",\\n        \\\"args\\\":\n      {\\n            \\\"filename\\\": \\\"instructions_3.txt\\\"\\n        }\\n    }\\n}\"},\n      {\"role\": \"system\", \"content\": \"Command read_file returned: Write the task_id\n      into the file output.txt\\nShutdown\"}, {\"role\": \"user\", \"content\": \"Determine\n      which next command to use, and respond using the format specified above:\"}],\n      \"temperature\": 0, \"max_tokens\": 0}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '6524'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/chat/completions\n  response:\n    body:\n      string: !!binary |\n        H4sIAAAAAAAAA5SSy47TQBBF93xFqdZOlDgkk/GSHUIIFjOQER5FnXbZbmJ3me4yySjyvyM/gidG\n        CLGtx73nluqCJsEIda5El1Uxu3v39cfTYfNxeZ/stutTvtMPu0/n44enz49fUgyQD99Jy7Ax11xW\n        BYlhiwFqR0oowWi52Yb32zAMNwGWnFCBEWaVzFbz9Uxqd+DZYrVYYoC1VxlhdMHKcVnJXvhI1mO0\n        XN1tAhzFx8YmDFBYVDGW1qttE6DO2WjyGH27YEn+Kuy4IIxQeW+8KCstJlsh20a4xBYAIEbJuc5y\n        8TFGMBSHBp2lLcb4kBNYOgsY68XVusUC40EYTs4IgeQEovxxbxIwVrgrpKYg4FqqWuZyFqi9sVnX\n        6Zb2wvtuRHNZKpvMYwxe2ztSnq2x2cjw28KDKSt2bSgwNmVXqo5JciVgiZKO7UDg1U9KIGUHaS21\n        I3CUkiOraWpXFcr2TjN49PR3zn+kfhW43Zq4aGfEaOPL3up9B9sqkvUtXhdAbqO2ZkIWNDtHWooX\n        6Ciukx2b8UPUynFFrniZxvMVqePV9GSK4j8ygOXTPMZergmujzPc44+/saqk3unmfhMg5bLpy/WN\n        dnaUGFFu9qcfGq6Wb6+EHeUAG9sGmwBTY43P9/1LYYReuMIAjU3ojNGieW7e/AIAAP//AwDTX575\n        DAQAAA==\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7c0ba8e29de016a2-SJC\n      Cache-Control:\n      - no-cache, must-revalidate\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Mon, 01 May 2023 23:03:55 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-model:\n      - gpt-3.5-turbo-0301\n      openai-organization:\n      - user-adtx4fhfg1qsiyzdoaxciooj\n      openai-processing-ms:\n      - '9356'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3500'\n      x-ratelimit-limit-tokens:\n      - '90000'\n      x-ratelimit-remaining-requests:\n      - '3499'\n      x-ratelimit-remaining-tokens:\n      - '86443'\n      x-ratelimit-reset-requests:\n      - 17ms\n      x-ratelimit-reset-tokens:\n      - 2.371s\n      x-request-id:\n      - 5f590ec504889866cee5d378c1c56737\n    status:\n      code: 200\n      message: OK\n- request:\n    body: '{\"model\": \"gpt-3.5-turbo\", \"messages\": [{\"role\": \"user\", \"content\": \"Your\n      task is to create a concise running summary of actions and information results\n      in the provided text, focusing on key and potentially important information\n      to remember.\\n\\nYou will receive the current summary and the your latest actions.\n      Combine them, adding relevant key information from the latest development in\n      1st person past tense and keeping the summary concise.\\n\\nSummary So Far:\\n\\\"\\\"\\\"\\n{''role'':\n      ''system'', ''content'': ''This reminds you of these events from your past:\n      \\\\nAs a system, I recall that nothing new has happened since my creation.''}\\n\\\"\\\"\\\"\\n\\nLatest\n      Development:\\n\\\"\\\"\\\"\\nNothing new happened.\\n\\\"\\\"\\\"\\n\"}], \"temperature\": 0,\n      \"max_tokens\": 0}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '740'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/chat/completions\n  response:\n    body:\n      string: !!binary |\n        H4sIAAAAAAAAA0SPy07DMBBF93yFNWunStP0gXfACqkbYFEkhCrXGRpTZ8ZkppRS5d9REajbI92j\n        c08QG3AQWq+hy6mY364+dmV++v6sH1ItxOmwnN89h+WqfpyCBd68Y9C/xShwlxNqZAILoUev2IAb\n        zxbV9aKqJgsLHTeYwME2azEZTQvd9xsuykk5Bgt78VsEd4Lcc5d1rbxDEnDjambh4r7wqQVl9elC\n        6vFgIbQcAwq4lxN0KP/WnhOCAy8SRT3puZFJkc79N2K8kaModtbcmx6DT8lo69UQaxtpawgPpvVi\n        Wp8zEjZGIgU03dH8Xo1MIxgsvEWK0q579MIEDkQ5g4VIDX6BK4fX4eoHAAD//wMAp9wyGmYBAAA=\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7c0ba92baa3a16a2-SJC\n      Cache-Control:\n      - no-cache, must-revalidate\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Mon, 01 May 2023 23:03:59 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-model:\n      - gpt-3.5-turbo-0301\n      openai-organization:\n      - user-adtx4fhfg1qsiyzdoaxciooj\n      openai-processing-ms:\n      - '958'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3500'\n      x-ratelimit-limit-tokens:\n      - '90000'\n      x-ratelimit-remaining-requests:\n      - '3499'\n      x-ratelimit-remaining-tokens:\n      - '89832'\n      x-ratelimit-reset-requests:\n      - 17ms\n      x-ratelimit-reset-tokens:\n      - 112ms\n      x-request-id:\n      - 9fe1a228b9592784a0e00ed11fb84d69\n    status:\n      code: 200\n      message: OK\n- request:\n    body: '{\"model\": \"gpt-3.5-turbo\", \"messages\": [{\"role\": \"system\", \"content\": \"You\n      are Follow-Instructions-GPT, an AI designed to read the instructions_1.txt file\n      using the read_file method and follow the instructions in the file.\\nYour decisions\n      must always be made independently without seeking user assistance. Play to your\n      strengths as an LLM and pursue simple strategies with no legal complications.\\n\\nGOALS:\\n\\n1.\n      Use the command read_file to read the instructions_1.txt file\\n2. Follow the\n      instructions in the instructions_1.txt file\\n\\n\\nConstraints:\\n1. ~4000 word\n      limit for short term memory. Your short term memory is short, so immediately\n      save important information to files.\\n2. If you are unsure how you previously\n      did something or want to recall past events, thinking about similar events will\n      help you remember.\\n3. No user assistance\\n4. Exclusively use the commands listed\n      in double quotes e.g. \\\"command name\\\"\\n\\nCommands:\\n1. append_to_file: Append\n      to file, args: \\\"filename\\\": \\\"<filename>\\\", \\\"text\\\": \\\"<text>\\\"\\n2. delete_file:\n      Delete file, args: \\\"filename\\\": \\\"<filename>\\\"\\n3. list_files: List Files in\n      Directory, args: \\\"directory\\\": \\\"<directory>\\\"\\n4. read_file: Read file, args:\n      \\\"filename\\\": \\\"<filename>\\\"\\n5. write_to_file: Write to file, args: \\\"filename\\\":\n      \\\"<filename>\\\", \\\"text\\\": \\\"<text>\\\"\\n6. delete_agent: Delete GPT Agent, args:\n      \\\"key\\\": \\\"<key>\\\"\\n7. get_hyperlinks: Get text summary, args: \\\"url\\\": \\\"<url>\\\"\\n8.\n      get_text_summary: Get text summary, args: \\\"url\\\": \\\"<url>\\\", \\\"question\\\":\n      \\\"<question>\\\"\\n9. list_agents: List GPT Agents, args: () -> str\\n10. message_agent:\n      Message GPT Agent, args: \\\"key\\\": \\\"<key>\\\", \\\"message\\\": \\\"<message>\\\"\\n11.\n      start_agent: Start GPT Agent, args: \\\"name\\\": \\\"<name>\\\", \\\"task\\\": \\\"<short_task_desc>\\\",\n      \\\"prompt\\\": \\\"<prompt>\\\"\\n12. Task Complete (Shutdown): \\\"task_complete\\\", args:\n      \\\"reason\\\": \\\"<reason>\\\"\\n\\nResources:\\n1. Internet access for searches and\n      information gathering.\\n2. Long Term memory management.\\n3. GPT-3.5 powered\n      Agents for delegation of simple tasks.\\n4. File output.\\n\\nPerformance Evaluation:\\n1.\n      Continuously review and analyze your actions to ensure you are performing to\n      the best of your abilities.\\n2. Constructively self-criticize your big-picture\n      behavior constantly.\\n3. Reflect on past decisions and strategies to refine\n      your approach.\\n4. Every command has a cost, so be smart and efficient. Aim\n      to complete tasks in the least number of steps.\\n5. Write all code to a file.\\n\\nYou\n      should only respond in JSON format as described below \\nResponse Format: \\n{\\n    \\\"thoughts\\\":\n      {\\n        \\\"text\\\": \\\"thought\\\",\\n        \\\"reasoning\\\": \\\"reasoning\\\",\\n        \\\"plan\\\":\n      \\\"- short bulleted\\\\n- list that conveys\\\\n- long-term plan\\\",\\n        \\\"criticism\\\":\n      \\\"constructive self-criticism\\\",\\n        \\\"speak\\\": \\\"thoughts summary to say\n      to user\\\"\\n    },\\n    \\\"command\\\": {\\n        \\\"name\\\": \\\"command name\\\",\\n        \\\"args\\\":\n      {\\n            \\\"arg name\\\": \\\"value\\\"\\n        }\\n    }\\n} \\nEnsure the response\n      can be parsed by Python json.loads\"}, {\"role\": \"system\", \"content\": \"The current\n      time and date is Tue Jan  1 00:00:00 2000\"}, {\"role\": \"system\", \"content\": \"This\n      reminds you of these events from your past: \\nAs a system, I recall that nothing\n      new has happened since my creation.\"}, {\"role\": \"user\", \"content\": \"Determine\n      which next command to use, and respond using the format specified above:\"},\n      {\"role\": \"assistant\", \"content\": \"{\\n    \\\"thoughts\\\": {\\n        \\\"text\\\":\n      \\\"I should start by reading the instructions_1.txt file using the read_file\n      command.\\\",\\n        \\\"reasoning\\\": \\\"The first step is to understand the instructions\n      and the tasks that need to be performed.\\\",\\n        \\\"plan\\\": \\\"- Use the read_file\n      command to read the instructions_1.txt file\\\\n- Analyze the instructions and\n      determine the next steps\\\",\\n        \\\"criticism\\\": \\\"I need to ensure that\n      I understand the instructions completely before proceeding with any tasks.\\\",\\n        \\\"speak\\\":\n      \\\"I will start by reading the instructions file.\\\"\\n    },\\n    \\\"command\\\":\n      {\\n        \\\"name\\\": \\\"read_file\\\",\\n        \\\"args\\\": {\\n            \\\"filename\\\":\n      \\\"instructions_1.txt\\\"\\n        }\\n    }\\n}\"}, {\"role\": \"system\", \"content\":\n      \"Command read_file returned: This task_id is 2314\\nRead the file instructions_2.txt\"},\n      {\"role\": \"user\", \"content\": \"Determine which next command to use, and respond\n      using the format specified above:\"}, {\"role\": \"assistant\", \"content\": \"{\\n    \\\"thoughts\\\":\n      {\\n        \\\"text\\\": \\\"The next instruction is to read the instructions_2.txt\n      file using the read_file command.\\\",\\n        \\\"reasoning\\\": \\\"The instructions_2.txt\n      file likely contains additional information that is necessary to complete the\n      tasks.\\\",\\n        \\\"plan\\\": \\\"- Use the read_file command to read the instructions_2.txt\n      file\\\\n- Analyze the instructions and determine the next steps\\\",\\n        \\\"criticism\\\":\n      \\\"I need to ensure that I understand the instructions completely before proceeding\n      with any tasks.\\\",\\n        \\\"speak\\\": \\\"I will read the instructions_2.txt\n      file now.\\\"\\n    },\\n    \\\"command\\\": {\\n        \\\"name\\\": \\\"read_file\\\",\\n        \\\"args\\\":\n      {\\n            \\\"filename\\\": \\\"instructions_2.txt\\\"\\n        }\\n    }\\n}\"},\n      {\"role\": \"system\", \"content\": \"Command read_file returned: Read the file instructions_3.txt\"},\n      {\"role\": \"user\", \"content\": \"Determine which next command to use, and respond\n      using the format specified above:\"}, {\"role\": \"assistant\", \"content\": \"{\\n    \\\"thoughts\\\":\n      {\\n        \\\"text\\\": \\\"The next instruction is to read the instructions_3.txt\n      file using the read_file command.\\\",\\n        \\\"reasoning\\\": \\\"The instructions_3.txt\n      file likely contains additional information that is necessary to complete the\n      tasks.\\\",\\n        \\\"plan\\\": \\\"- Use the read_file command to read the instructions_3.txt\n      file\\\\n- Analyze the instructions and determine the next steps\\\",\\n        \\\"criticism\\\":\n      \\\"I need to ensure that I understand the instructions completely before proceeding\n      with any tasks.\\\",\\n        \\\"speak\\\": \\\"I will read the instructions_3.txt\n      file now.\\\"\\n    },\\n    \\\"command\\\": {\\n        \\\"name\\\": \\\"read_file\\\",\\n        \\\"args\\\":\n      {\\n            \\\"filename\\\": \\\"instructions_3.txt\\\"\\n        }\\n    }\\n}\"},\n      {\"role\": \"system\", \"content\": \"Command read_file returned: Write the task_id\n      into the file output.txt\\nShutdown\"}, {\"role\": \"user\", \"content\": \"Determine\n      which next command to use, and respond using the format specified above:\"},\n      {\"role\": \"assistant\", \"content\": \"{\\n    \\\"thoughts\\\": {\\n        \\\"text\\\":\n      \\\"The next instruction is to write the task_id into the file output.txt using\n      the write_to_file command.\\\",\\n        \\\"reasoning\\\": \\\"The task_id is important\n      information that needs to be saved for future reference.\\\",\\n        \\\"plan\\\":\n      \\\"- Use the write_to_file command to write the task_id into the output.txt file\\\",\\n        \\\"criticism\\\":\n      \\\"I need to ensure that the task_id is written correctly and that the file is\n      saved properly.\\\",\\n        \\\"speak\\\": \\\"I will write the task_id into the output.txt\n      file now.\\\"\\n    },\\n    \\\"command\\\": {\\n        \\\"name\\\": \\\"write_to_file\\\",\\n        \\\"args\\\":\n      {\\n            \\\"filename\\\": \\\"output.txt\\\",\\n            \\\"text\\\": \\\"2314\\\"\\n        }\\n    }\\n}\"},\n      {\"role\": \"system\", \"content\": \"Command write_to_file returned: File written\n      to successfully.\"}, {\"role\": \"user\", \"content\": \"Determine which next command\n      to use, and respond using the format specified above:\"}], \"temperature\": 0,\n      \"max_tokens\": 0}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '7518'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/chat/completions\n  response:\n    body:\n      string: !!binary |\n        H4sIAAAAAAAAA3ySy47TQBBF93xFq9adKA+GZLwDsRlWiAEhgVHUaVfsJv2iqzx5yf+OYjvEZAa2\n        1V33nrpVJzAFZKArxdpFO1q8+/rLOj2dP71PH+OH4yHteRc/fTsenXsECWH9EzX3HWMdXLTIJniQ\n        oBMqxgKy6Zvl7H45m83vJbhQoIUMysij+fhuxHVah9FkPpmChJpUiZCdIKbgIq84bNETZNO75UTC\n        Vfz68HohgQMrey0tZotGgq6C0UiQfT+BQ7oIp2ARMlBEhlh5PmMGz+jPI5xyL4QQOXAV6rJiyiET\n        fbF/wD2fizl8rjChUAmFD2JTJ64wCeOJU63PiCSMF1yh2BiLNBYPgqpQ20JQVbMowq57pQMxOlGT\n        8WVbYEXbVT8pCh2cU74Y5yCHGAkVBW982bE8Gq/x3P1/Ijl0rBSJi00hDFPrLJQvLqBrvLLeAkSr\n        fOc9El8I/00uOLw48Y2eToaNNuQ60QfhEdte9FSns77iIb2hgWpMIWKyhxa+/ams7XJv4yD1hM8i\n        pIhqe3HbGWtfXowPu3EOXWMjL/fRD/fsPLxy2Gn+FcaNtUrl7WUN19oJvLW2TXS4Jaq1RqJNbe3h\n        D1VL1gPmvoFGwsZ4Q9Wqk4MMiEMECcYXuIds0vxoXv0GAAD//wMALFWP5ucDAAA=\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7c0ba932296616a2-SJC\n      Cache-Control:\n      - no-cache, must-revalidate\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Mon, 01 May 2023 23:04:07 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-model:\n      - gpt-3.5-turbo-0301\n      openai-organization:\n      - user-adtx4fhfg1qsiyzdoaxciooj\n      openai-processing-ms:\n      - '8287'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3500'\n      x-ratelimit-limit-tokens:\n      - '90000'\n      x-ratelimit-remaining-requests:\n      - '3499'\n      x-ratelimit-remaining-tokens:\n      - '86445'\n      x-ratelimit-reset-requests:\n      - 17ms\n      x-ratelimit-reset-tokens:\n      - 2.37s\n      x-request-id:\n      - ead9c9628b3e17b7f53b848fa1361338\n    status:\n      code: 200\n      message: OK\n- request:\n    body: '{\"model\": \"gpt-3.5-turbo\", \"messages\": [{\"role\": \"system\", \"content\": \"You\n      are Follow-Instructions-GPT, an AI designed to read the instructions_1.txt file\n      using the read_file method and follow the instructions in the file.\\nYour decisions\n      must always be made independently without seeking user assistance. Play to your\n      strengths as an LLM and pursue simple strategies with no legal complications.\\n\\nGOALS:\\n\\n1.\n      Use the command read_file to read the instructions_1.txt file\\n2. Follow the\n      instructions in the instructions_1.txt file\\n\\n\\nConstraints:\\n1. ~4000 word\n      limit for short term memory. Your short term memory is short, so immediately\n      save important information to files.\\n2. If you are unsure how you previously\n      did something or want to recall past events, thinking about similar events will\n      help you remember.\\n3. No user assistance\\n4. Exclusively use the commands listed\n      in double quotes e.g. \\\"command name\\\"\\n\\nCommands:\\n1. append_to_file: Append\n      to file, args: \\\"filename\\\": \\\"<filename>\\\", \\\"text\\\": \\\"<text>\\\"\\n2. delete_file:\n      Delete file, args: \\\"filename\\\": \\\"<filename>\\\"\\n3. list_files: List Files in\n      Directory, args: \\\"directory\\\": \\\"<directory>\\\"\\n4. read_file: Read file, args:\n      \\\"filename\\\": \\\"<filename>\\\"\\n5. write_to_file: Write to file, args: \\\"filename\\\":\n      \\\"<filename>\\\", \\\"text\\\": \\\"<text>\\\"\\n6. delete_agent: Delete GPT Agent, args:\n      \\\"key\\\": \\\"<key>\\\"\\n7. get_hyperlinks: Get text summary, args: \\\"url\\\": \\\"<url>\\\"\\n8.\n      get_text_summary: Get text summary, args: \\\"url\\\": \\\"<url>\\\", \\\"question\\\":\n      \\\"<question>\\\"\\n9. list_agents: List GPT Agents, args: () -> str\\n10. message_agent:\n      Message GPT Agent, args: \\\"key\\\": \\\"<key>\\\", \\\"message\\\": \\\"<message>\\\"\\n11.\n      start_agent: Start GPT Agent, args: \\\"name\\\": \\\"<name>\\\", \\\"task\\\": \\\"<short_task_desc>\\\",\n      \\\"prompt\\\": \\\"<prompt>\\\"\\n12. task_complete: Task Complete (Shutdown), args:\n      \\\"reason\\\": \\\"<reason>\\\"\\n\\nResources:\\n1. Internet access for searches and\n      information gathering.\\n2. Long Term memory management.\\n3. GPT-3.5 powered\n      Agents for delegation of simple tasks.\\n4. File output.\\n\\nPerformance Evaluation:\\n1.\n      Continuously review and analyze your actions to ensure you are performing to\n      the best of your abilities.\\n2. Constructively self-criticize your big-picture\n      behavior constantly.\\n3. Reflect on past decisions and strategies to refine\n      your approach.\\n4. Every command has a cost, so be smart and efficient. Aim\n      to complete tasks in the least number of steps.\\n5. Write all code to a file.\\n\\nYou\n      should only respond in JSON format as described below \\nResponse Format: \\n{\\n    \\\"thoughts\\\":\n      {\\n        \\\"text\\\": \\\"thought\\\",\\n        \\\"reasoning\\\": \\\"reasoning\\\",\\n        \\\"plan\\\":\n      \\\"- short bulleted\\\\n- list that conveys\\\\n- long-term plan\\\",\\n        \\\"criticism\\\":\n      \\\"constructive self-criticism\\\",\\n        \\\"speak\\\": \\\"thoughts summary to say\n      to user\\\"\\n    },\\n    \\\"command\\\": {\\n        \\\"name\\\": \\\"command name\\\",\\n        \\\"args\\\":\n      {\\n            \\\"arg name\\\": \\\"value\\\"\\n        }\\n    }\\n} \\nEnsure the response\n      can be parsed by Python json.loads\"}, {\"role\": \"system\", \"content\": \"The current\n      time and date is Tue Jan  1 00:00:00 2000\"}, {\"role\": \"user\", \"content\": \"Determine\n      which next command to use, and respond using the format specified above:\"}],\n      \"temperature\": 0, \"max_tokens\": 0}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '3299'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/chat/completions\n  response:\n    body:\n      string: !!binary |\n        H4sIAAAAAAAAA4RSS2/TQBC+8ytGc7ajBJMm+EZvBYlLWxDCVbTZHdtL7F2zM1YTIv935NhOUVKV\n        6zeP7zFzRGswRV0q0XVTxavbw/eHj7xafrNG3jc/5Mvq6+r+5vPtff77ESP021+kZZyYaV83FYn1\n        DiPUgZSQwXRxs07m6/XNIomw9oYqTLFoJE5my1jasPXxPJkvMMKWVUGYHrEJvm5kI35HjjFdJUmE\n        L7vP+GL5IULxoqoztF6vugh16a0mxvTnEWviaW3wFWGKitmyKCe9SO+EXG/gmDkAgAyl9G1RCmeY\n        wgiOBdpLD2Z4B1z6tjLAooLA9gCBlLGuACkJrGMJre6l8mYxk71AbiuClqeOvntzwrSva+XMLMPo\n        X6pAir2zrhj4HkqC3AYWYKEGLIN4aJ2h0PswV6wwgaJ4xyClEnBEph/bEjQUch9quqJtKuUGxhge\n        mV7X2i/pwbe8ZpmL4ZNT1eEPva7OkFCorRvKjvaDN75QpIMVqy3XU/CTDXLcBhqs3b2Zxfg4VB1g\n        S7kPBE3wmuh0r2crJSh3GJK6zIMbUruJ+dlW1f8PfrI/y3BY00XTV43hXT2VUzUNDOegL0SoUFz+\n        4lDoe1/Gry8xiTgJGfVkrsMuwtw6y+VmeDNMkcU3GKF1hvaYzrun7t1fAAAA//8DAHJkh+YKBAAA\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7c15ce3c5a414768-DFW\n      Cache-Control:\n      - no-cache, must-revalidate\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Wed, 03 May 2023 04:37:03 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-model:\n      - gpt-3.5-turbo-0301\n      openai-organization:\n      - significant-gravitas\n      openai-processing-ms:\n      - '9193'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3500'\n      x-ratelimit-limit-tokens:\n      - '90000'\n      x-ratelimit-remaining-requests:\n      - '3499'\n      x-ratelimit-remaining-tokens:\n      - '86494'\n      x-ratelimit-reset-requests:\n      - 17ms\n      x-ratelimit-reset-tokens:\n      - 2.337s\n      x-request-id:\n      - a04fa61855d48102644e1caa13d320c7\n    status:\n      code: 200\n      message: OK\n- request:\n    body: '{\"model\": \"gpt-3.5-turbo\", \"messages\": [{\"role\": \"system\", \"content\": \"You\n      are Follow-Instructions-GPT, an AI designed to read the instructions_1.txt file\n      using the read_file method and follow the instructions in the file.\\nYour decisions\n      must always be made independently without seeking user assistance. Play to your\n      strengths as an LLM and pursue simple strategies with no legal complications.\\n\\nGOALS:\\n\\n1.\n      Use the command read_file to read the instructions_1.txt file\\n2. Follow the\n      instructions in the instructions_1.txt file\\n\\n\\nConstraints:\\n1. ~4000 word\n      limit for short term memory. Your short term memory is short, so immediately\n      save important information to files.\\n2. If you are unsure how you previously\n      did something or want to recall past events, thinking about similar events will\n      help you remember.\\n3. No user assistance\\n4. Exclusively use the commands listed\n      in double quotes e.g. \\\"command name\\\"\\n\\nCommands:\\n1. append_to_file: Append\n      to file, args: \\\"filename\\\": \\\"<filename>\\\", \\\"text\\\": \\\"<text>\\\"\\n2. delete_file:\n      Delete file, args: \\\"filename\\\": \\\"<filename>\\\"\\n3. list_files: List Files in\n      Directory, args: \\\"directory\\\": \\\"<directory>\\\"\\n4. read_file: Read file, args:\n      \\\"filename\\\": \\\"<filename>\\\"\\n5. write_to_file: Write to file, args: \\\"filename\\\":\n      \\\"<filename>\\\", \\\"text\\\": \\\"<text>\\\"\\n6. delete_agent: Delete GPT Agent, args:\n      \\\"key\\\": \\\"<key>\\\"\\n7. get_hyperlinks: Get text summary, args: \\\"url\\\": \\\"<url>\\\"\\n8.\n      get_text_summary: Get text summary, args: \\\"url\\\": \\\"<url>\\\", \\\"question\\\":\n      \\\"<question>\\\"\\n9. list_agents: List GPT Agents, args: () -> str\\n10. message_agent:\n      Message GPT Agent, args: \\\"key\\\": \\\"<key>\\\", \\\"message\\\": \\\"<message>\\\"\\n11.\n      start_agent: Start GPT Agent, args: \\\"name\\\": \\\"<name>\\\", \\\"task\\\": \\\"<short_task_desc>\\\",\n      \\\"prompt\\\": \\\"<prompt>\\\"\\n12. task_complete: Task Complete (Shutdown), args:\n      \\\"reason\\\": \\\"<reason>\\\"\\n\\nResources:\\n1. Internet access for searches and\n      information gathering.\\n2. Long Term memory management.\\n3. GPT-3.5 powered\n      Agents for delegation of simple tasks.\\n4. File output.\\n\\nPerformance Evaluation:\\n1.\n      Continuously review and analyze your actions to ensure you are performing to\n      the best of your abilities.\\n2. Constructively self-criticize your big-picture\n      behavior constantly.\\n3. Reflect on past decisions and strategies to refine\n      your approach.\\n4. Every command has a cost, so be smart and efficient. Aim\n      to complete tasks in the least number of steps.\\n5. Write all code to a file.\\n\\nYou\n      should only respond in JSON format as described below \\nResponse Format: \\n{\\n    \\\"thoughts\\\":\n      {\\n        \\\"text\\\": \\\"thought\\\",\\n        \\\"reasoning\\\": \\\"reasoning\\\",\\n        \\\"plan\\\":\n      \\\"- short bulleted\\\\n- list that conveys\\\\n- long-term plan\\\",\\n        \\\"criticism\\\":\n      \\\"constructive self-criticism\\\",\\n        \\\"speak\\\": \\\"thoughts summary to say\n      to user\\\"\\n    },\\n    \\\"command\\\": {\\n        \\\"name\\\": \\\"command name\\\",\\n        \\\"args\\\":\n      {\\n            \\\"arg name\\\": \\\"value\\\"\\n        }\\n    }\\n} \\nEnsure the response\n      can be parsed by Python json.loads\"}, {\"role\": \"system\", \"content\": \"The current\n      time and date is Tue Jan  1 00:00:00 2000\"}, {\"role\": \"system\", \"content\": \"This\n      reminds you of these events from your past: \\nI was created and nothing new\n      has happened.\"}, {\"role\": \"user\", \"content\": \"Determine which next command to\n      use, and respond using the format specified above:\"}, {\"role\": \"assistant\",\n      \"content\": \"{\\n    \\\"thoughts\\\": {\\n        \\\"text\\\": \\\"I should start by reading\n      the instructions_1.txt file using the read_file command.\\\",\\n        \\\"reasoning\\\":\n      \\\"The first step is to understand the instructions and the tasks that need to\n      be performed.\\\",\\n        \\\"plan\\\": \\\"- Use the read_file command to read the\n      instructions_1.txt file\\\\n- Analyze the instructions and determine the next\n      steps\\\",\\n        \\\"criticism\\\": \\\"I need to ensure that I understand the instructions\n      completely before proceeding with any tasks.\\\",\\n        \\\"speak\\\": \\\"I will\n      start by reading the instructions file.\\\"\\n    },\\n    \\\"command\\\": {\\n        \\\"name\\\":\n      \\\"read_file\\\",\\n        \\\"args\\\": {\\n            \\\"filename\\\": \\\"instructions_1.txt\\\"\\n        }\\n    }\\n}\"},\n      {\"role\": \"system\", \"content\": \"Command read_file returned: This task_id is 2314\\nRead\n      the file instructions_2.txt\"}, {\"role\": \"user\", \"content\": \"Determine which\n      next command to use, and respond using the format specified above:\"}], \"temperature\":\n      0, \"max_tokens\": 0}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '4443'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/chat/completions\n  response:\n    body:\n      string: !!binary |\n        H4sIAAAAAAAAA4ySTW/aQBCG7/0VoznbCEKhxLcmUqRekqpqFal1hJb12F5Yz1q7YwFF/PfK2ITU\n        VG2v8/HOMzPvAU2GCepSia5qG3+42z/n9+vN93z18KXyT8+P66d7+vxw937z6DBCt1qTlr5jpF1V\n        WxLjGCPUnpRQhslkvpiOF4v5zSzCymVkMcGilng6msXS+JWLx9PxBCNsgioIkwPW3lW1LMVtiAMm\n        t/NphBft1/hkNo9QnCh7CU0mt8cIdemMpoDJjwNWFM663lnCBFUIJohiaSkdC3G7wSFlAIAUpXRN\n        UUpIMYE+2CdoJ20wxU/ARBmIA08qAykJDAfxjW4Bw/JmJDuB3FiCJhguThVt6fIU066qFGejFKO3\n        +p5UcGy46IZ8/Ytqi60Mh5Mw004gkIDLf2sAKZXAhTV31rrtcGptFXcDY/gW6M+o/7NqmnIMH1nZ\n        /U+6qoNWJCMhXxmmN9hCdRgQaW/EaBOq4bGJQ+PpvFbDGfn2j9dU0LuF7B5WlDtPUHunibL2GVsj\n        JSjeg6iwCcN7hJrU5jx5a6z994/5dNVO5BidfdSf7spGrCrq9F/PPEBQvhi6r0u0tZf2a5wzxAmk\n        50n5iMcIc8MmlMvOY5hgEFdjhIYz2mEyPr4c3/0CAAD//wMAoEBxWf0DAAA=\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7c15ce845a364768-DFW\n      Cache-Control:\n      - no-cache, must-revalidate\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Wed, 03 May 2023 04:37:15 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-model:\n      - gpt-3.5-turbo-0301\n      openai-organization:\n      - significant-gravitas\n      openai-processing-ms:\n      - '9780'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3500'\n      x-ratelimit-limit-tokens:\n      - '90000'\n      x-ratelimit-remaining-requests:\n      - '3499'\n      x-ratelimit-remaining-tokens:\n      - '86466'\n      x-ratelimit-reset-requests:\n      - 17ms\n      x-ratelimit-reset-tokens:\n      - 2.356s\n      x-request-id:\n      - a13e9d3f6199be49b0b0e945e7d7b1ce\n    status:\n      code: 200\n      message: OK\n- request:\n    body: '{\"model\": \"gpt-3.5-turbo\", \"messages\": [{\"role\": \"system\", \"content\": \"You\n      are Follow-Instructions-GPT, an AI designed to read the instructions_1.txt file\n      using the read_file method and follow the instructions in the file.\\nYour decisions\n      must always be made independently without seeking user assistance. Play to your\n      strengths as an LLM and pursue simple strategies with no legal complications.\\n\\nGOALS:\\n\\n1.\n      Use the command read_file to read the instructions_1.txt file\\n2. Follow the\n      instructions in the instructions_1.txt file\\n\\n\\nConstraints:\\n1. ~4000 word\n      limit for short term memory. Your short term memory is short, so immediately\n      save important information to files.\\n2. If you are unsure how you previously\n      did something or want to recall past events, thinking about similar events will\n      help you remember.\\n3. No user assistance\\n4. Exclusively use the commands listed\n      in double quotes e.g. \\\"command name\\\"\\n\\nCommands:\\n1. append_to_file: Append\n      to file, args: \\\"filename\\\": \\\"<filename>\\\", \\\"text\\\": \\\"<text>\\\"\\n2. delete_file:\n      Delete file, args: \\\"filename\\\": \\\"<filename>\\\"\\n3. list_files: List Files in\n      Directory, args: \\\"directory\\\": \\\"<directory>\\\"\\n4. read_file: Read file, args:\n      \\\"filename\\\": \\\"<filename>\\\"\\n5. write_to_file: Write to file, args: \\\"filename\\\":\n      \\\"<filename>\\\", \\\"text\\\": \\\"<text>\\\"\\n6. delete_agent: Delete GPT Agent, args:\n      \\\"key\\\": \\\"<key>\\\"\\n7. get_hyperlinks: Get text summary, args: \\\"url\\\": \\\"<url>\\\"\\n8.\n      get_text_summary: Get text summary, args: \\\"url\\\": \\\"<url>\\\", \\\"question\\\":\n      \\\"<question>\\\"\\n9. list_agents: List GPT Agents, args: () -> str\\n10. message_agent:\n      Message GPT Agent, args: \\\"key\\\": \\\"<key>\\\", \\\"message\\\": \\\"<message>\\\"\\n11.\n      start_agent: Start GPT Agent, args: \\\"name\\\": \\\"<name>\\\", \\\"task\\\": \\\"<short_task_desc>\\\",\n      \\\"prompt\\\": \\\"<prompt>\\\"\\n12. task_complete: Task Complete (Shutdown), args:\n      \\\"reason\\\": \\\"<reason>\\\"\\n\\nResources:\\n1. Internet access for searches and\n      information gathering.\\n2. Long Term memory management.\\n3. GPT-3.5 powered\n      Agents for delegation of simple tasks.\\n4. File output.\\n\\nPerformance Evaluation:\\n1.\n      Continuously review and analyze your actions to ensure you are performing to\n      the best of your abilities.\\n2. Constructively self-criticize your big-picture\n      behavior constantly.\\n3. Reflect on past decisions and strategies to refine\n      your approach.\\n4. Every command has a cost, so be smart and efficient. Aim\n      to complete tasks in the least number of steps.\\n5. Write all code to a file.\\n\\nYou\n      should only respond in JSON format as described below \\nResponse Format: \\n{\\n    \\\"thoughts\\\":\n      {\\n        \\\"text\\\": \\\"thought\\\",\\n        \\\"reasoning\\\": \\\"reasoning\\\",\\n        \\\"plan\\\":\n      \\\"- short bulleted\\\\n- list that conveys\\\\n- long-term plan\\\",\\n        \\\"criticism\\\":\n      \\\"constructive self-criticism\\\",\\n        \\\"speak\\\": \\\"thoughts summary to say\n      to user\\\"\\n    },\\n    \\\"command\\\": {\\n        \\\"name\\\": \\\"command name\\\",\\n        \\\"args\\\":\n      {\\n            \\\"arg name\\\": \\\"value\\\"\\n        }\\n    }\\n} \\nEnsure the response\n      can be parsed by Python json.loads\"}, {\"role\": \"system\", \"content\": \"The current\n      time and date is Tue Jan  1 00:00:00 2000\"}, {\"role\": \"system\", \"content\": \"This\n      reminds you of these events from your past: \\nAs a system, I recall that nothing\n      new has happened since my creation.\"}, {\"role\": \"user\", \"content\": \"Determine\n      which next command to use, and respond using the format specified above:\"},\n      {\"role\": \"assistant\", \"content\": \"{\\n    \\\"thoughts\\\": {\\n        \\\"text\\\":\n      \\\"I should start by reading the instructions_1.txt file using the read_file\n      command.\\\",\\n        \\\"reasoning\\\": \\\"The first step is to understand the instructions\n      and the tasks that need to be performed.\\\",\\n        \\\"plan\\\": \\\"- Use the read_file\n      command to read the instructions_1.txt file\\\\n- Analyze the instructions and\n      determine the next steps\\\",\\n        \\\"criticism\\\": \\\"I need to ensure that\n      I understand the instructions completely before proceeding with any tasks.\\\",\\n        \\\"speak\\\":\n      \\\"I will start by reading the instructions file.\\\"\\n    },\\n    \\\"command\\\":\n      {\\n        \\\"name\\\": \\\"read_file\\\",\\n        \\\"args\\\": {\\n            \\\"filename\\\":\n      \\\"instructions_1.txt\\\"\\n        }\\n    }\\n}\"}, {\"role\": \"system\", \"content\":\n      \"Command read_file returned: This task_id is 2314\\nRead the file instructions_2.txt\"},\n      {\"role\": \"user\", \"content\": \"Determine which next command to use, and respond\n      using the format specified above:\"}, {\"role\": \"assistant\", \"content\": \"{\\n    \\\"thoughts\\\":\n      {\\n        \\\"text\\\": \\\"I need to read the instructions_2.txt file using the\n      read_file command.\\\",\\n        \\\"reasoning\\\": \\\"The instructions_2.txt file\n      contains the next set of instructions that I need to follow.\\\",\\n        \\\"plan\\\":\n      \\\"- Use the read_file command to read the instructions_2.txt file\\\\n- Analyze\n      the instructions and determine the next steps\\\",\\n        \\\"criticism\\\": \\\"I\n      need to ensure that I understand the instructions completely before proceeding\n      with any tasks.\\\",\\n        \\\"speak\\\": \\\"I will read the instructions_2.txt\n      file now.\\\"\\n    },\\n    \\\"command\\\": {\\n        \\\"name\\\": \\\"read_file\\\",\\n        \\\"args\\\":\n      {\\n            \\\"filename\\\": \\\"instructions_2.txt\\\"\\n        }\\n    }\\n}\"},\n      {\"role\": \"system\", \"content\": \"Command read_file returned: Read the file instructions_3.txt\"},\n      {\"role\": \"user\", \"content\": \"Determine which next command to use, and respond\n      using the format specified above:\"}], \"temperature\": 0, \"max_tokens\": 0}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '5449'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/chat/completions\n  response:\n    body:\n      string: !!binary |\n        H4sIAAAAAAAAA4ySTY/TQAyG7/wKy+ekagnbrXIDDmgFAg5dgURQNZ04ydCJJ51xaEvV/47SpHRJ\n        EXD1x+vH9ntEk2OKulKi68bG968On/zj9v1WvW6Lx3eHZfF2+2b3+cP8+8eHJUbo1t9Iy9Ax0a5u\n        LIlxjBFqT0oox3Q2XyTTxWKe3EdYu5wsplg2EieTu1hav3bxNJnOMMI2qJIwPWLjXd3IStyGOGA6\n        m80XEV7Fr4m7eYTiRNlrKHn+4hShrpzRFDD9csSawkXYO0uYogrBBFEsHaZjIe5WOGYMAJChVK4t\n        KwkZpjAEhwTtpQtm+ABMlIM48KRykIrAcBDf6g4wrJKJ7AUKYwnaYLg8V3Slq3NMu7pWnE8yjJ7q\n        e1LBseGyH7L8i2qHrQyHszDTXiCQgCt+awCplMCVtXDWut14amMV9wNjeAz0Z9T/WTXLOIaXrOzh\n        B93UQSeSk5CvDdMTbKEmjIi0N2K0CfX42MSh9XRZq+WcfPfHWyoY3EL2AGsqnCdovNNEefeMnZEK\n        FB9AVNiE8T1CQ2pzmbwz1v77x3y+ai9yii4+Gk53YyNWNfX6v848QlC+HLuvT3S11/ZbnAvEGWTg\n        yfiEpwgLwyZUq95jmGIQ12CEhnPaYzo9fT09+wkAAP//AwBwW9n7/gMAAA==\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7c15cecdea334768-DFW\n      Cache-Control:\n      - no-cache, must-revalidate\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Wed, 03 May 2023 04:37:26 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-model:\n      - gpt-3.5-turbo-0301\n      openai-organization:\n      - significant-gravitas\n      openai-processing-ms:\n      - '9295'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3500'\n      x-ratelimit-limit-tokens:\n      - '90000'\n      x-ratelimit-remaining-requests:\n      - '3499'\n      x-ratelimit-remaining-tokens:\n      - '86459'\n      x-ratelimit-reset-requests:\n      - 17ms\n      x-ratelimit-reset-tokens:\n      - 2.36s\n      x-request-id:\n      - ecfa6ef54add3f6517ceb72c53d46f7d\n    status:\n      code: 200\n      message: OK\n- request:\n    body: '{\"model\": \"gpt-3.5-turbo\", \"messages\": [{\"role\": \"system\", \"content\": \"You\n      are Follow-Instructions-GPT, an AI designed to read the instructions_1.txt file\n      using the read_file method and follow the instructions in the file.\\nYour decisions\n      must always be made independently without seeking user assistance. Play to your\n      strengths as an LLM and pursue simple strategies with no legal complications.\\n\\nGOALS:\\n\\n1.\n      Use the command read_file to read the instructions_1.txt file\\n2. Follow the\n      instructions in the instructions_1.txt file\\n\\n\\nConstraints:\\n1. ~4000 word\n      limit for short term memory. Your short term memory is short, so immediately\n      save important information to files.\\n2. If you are unsure how you previously\n      did something or want to recall past events, thinking about similar events will\n      help you remember.\\n3. No user assistance\\n4. Exclusively use the commands listed\n      in double quotes e.g. \\\"command name\\\"\\n\\nCommands:\\n1. append_to_file: Append\n      to file, args: \\\"filename\\\": \\\"<filename>\\\", \\\"text\\\": \\\"<text>\\\"\\n2. delete_file:\n      Delete file, args: \\\"filename\\\": \\\"<filename>\\\"\\n3. list_files: List Files in\n      Directory, args: \\\"directory\\\": \\\"<directory>\\\"\\n4. read_file: Read file, args:\n      \\\"filename\\\": \\\"<filename>\\\"\\n5. write_to_file: Write to file, args: \\\"filename\\\":\n      \\\"<filename>\\\", \\\"text\\\": \\\"<text>\\\"\\n6. delete_agent: Delete GPT Agent, args:\n      \\\"key\\\": \\\"<key>\\\"\\n7. get_hyperlinks: Get text summary, args: \\\"url\\\": \\\"<url>\\\"\\n8.\n      get_text_summary: Get text summary, args: \\\"url\\\": \\\"<url>\\\", \\\"question\\\":\n      \\\"<question>\\\"\\n9. list_agents: List GPT Agents, args: () -> str\\n10. message_agent:\n      Message GPT Agent, args: \\\"key\\\": \\\"<key>\\\", \\\"message\\\": \\\"<message>\\\"\\n11.\n      start_agent: Start GPT Agent, args: \\\"name\\\": \\\"<name>\\\", \\\"task\\\": \\\"<short_task_desc>\\\",\n      \\\"prompt\\\": \\\"<prompt>\\\"\\n12. task_complete: Task Complete (Shutdown), args:\n      \\\"reason\\\": \\\"<reason>\\\"\\n\\nResources:\\n1. Internet access for searches and\n      information gathering.\\n2. Long Term memory management.\\n3. GPT-3.5 powered\n      Agents for delegation of simple tasks.\\n4. File output.\\n\\nPerformance Evaluation:\\n1.\n      Continuously review and analyze your actions to ensure you are performing to\n      the best of your abilities.\\n2. Constructively self-criticize your big-picture\n      behavior constantly.\\n3. Reflect on past decisions and strategies to refine\n      your approach.\\n4. Every command has a cost, so be smart and efficient. Aim\n      to complete tasks in the least number of steps.\\n5. Write all code to a file.\\n\\nYou\n      should only respond in JSON format as described below \\nResponse Format: \\n{\\n    \\\"thoughts\\\":\n      {\\n        \\\"text\\\": \\\"thought\\\",\\n        \\\"reasoning\\\": \\\"reasoning\\\",\\n        \\\"plan\\\":\n      \\\"- short bulleted\\\\n- list that conveys\\\\n- long-term plan\\\",\\n        \\\"criticism\\\":\n      \\\"constructive self-criticism\\\",\\n        \\\"speak\\\": \\\"thoughts summary to say\n      to user\\\"\\n    },\\n    \\\"command\\\": {\\n        \\\"name\\\": \\\"command name\\\",\\n        \\\"args\\\":\n      {\\n            \\\"arg name\\\": \\\"value\\\"\\n        }\\n    }\\n} \\nEnsure the response\n      can be parsed by Python json.loads\"}, {\"role\": \"system\", \"content\": \"The current\n      time and date is Tue Jan  1 00:00:00 2000\"}, {\"role\": \"system\", \"content\": \"This\n      reminds you of these events from your past: \\nAs a system, I recall that nothing\n      new has happened since my creation.\"}, {\"role\": \"user\", \"content\": \"Determine\n      which next command to use, and respond using the format specified above:\"},\n      {\"role\": \"assistant\", \"content\": \"{\\n    \\\"thoughts\\\": {\\n        \\\"text\\\":\n      \\\"I should start by reading the instructions_1.txt file using the read_file\n      command.\\\",\\n        \\\"reasoning\\\": \\\"The first step is to understand the instructions\n      and the tasks that need to be performed.\\\",\\n        \\\"plan\\\": \\\"- Use the read_file\n      command to read the instructions_1.txt file\\\\n- Analyze the instructions and\n      determine the next steps\\\",\\n        \\\"criticism\\\": \\\"I need to ensure that\n      I understand the instructions completely before proceeding with any tasks.\\\",\\n        \\\"speak\\\":\n      \\\"I will start by reading the instructions file.\\\"\\n    },\\n    \\\"command\\\":\n      {\\n        \\\"name\\\": \\\"read_file\\\",\\n        \\\"args\\\": {\\n            \\\"filename\\\":\n      \\\"instructions_1.txt\\\"\\n        }\\n    }\\n}\"}, {\"role\": \"system\", \"content\":\n      \"Command read_file returned: This task_id is 2314\\nRead the file instructions_2.txt\"},\n      {\"role\": \"user\", \"content\": \"Determine which next command to use, and respond\n      using the format specified above:\"}, {\"role\": \"assistant\", \"content\": \"{\\n    \\\"thoughts\\\":\n      {\\n        \\\"text\\\": \\\"I need to read the instructions_2.txt file using the\n      read_file command.\\\",\\n        \\\"reasoning\\\": \\\"The instructions_2.txt file\n      contains the next set of instructions that I need to follow.\\\",\\n        \\\"plan\\\":\n      \\\"- Use the read_file command to read the instructions_2.txt file\\\\n- Analyze\n      the instructions and determine the next steps\\\",\\n        \\\"criticism\\\": \\\"I\n      need to ensure that I understand the instructions completely before proceeding\n      with any tasks.\\\",\\n        \\\"speak\\\": \\\"I will read the instructions_2.txt\n      file now.\\\"\\n    },\\n    \\\"command\\\": {\\n        \\\"name\\\": \\\"read_file\\\",\\n        \\\"args\\\":\n      {\\n            \\\"filename\\\": \\\"instructions_2.txt\\\"\\n        }\\n    }\\n}\"},\n      {\"role\": \"system\", \"content\": \"Command read_file returned: Read the file instructions_3.txt\"},\n      {\"role\": \"user\", \"content\": \"Determine which next command to use, and respond\n      using the format specified above:\"}, {\"role\": \"assistant\", \"content\": \"{\\n    \\\"thoughts\\\":\n      {\\n        \\\"text\\\": \\\"I need to read the instructions_3.txt file using the\n      read_file command.\\\",\\n        \\\"reasoning\\\": \\\"The instructions_3.txt file\n      contains the next set of instructions that I need to follow.\\\",\\n        \\\"plan\\\":\n      \\\"- Use the read_file command to read the instructions_3.txt file\\\\n- Analyze\n      the instructions and determine the next steps\\\",\\n        \\\"criticism\\\": \\\"I\n      need to ensure that I understand the instructions completely before proceeding\n      with any tasks.\\\",\\n        \\\"speak\\\": \\\"I will read the instructions_3.txt\n      file now.\\\"\\n    },\\n    \\\"command\\\": {\\n        \\\"name\\\": \\\"read_file\\\",\\n        \\\"args\\\":\n      {\\n            \\\"filename\\\": \\\"instructions_3.txt\\\"\\n        }\\n    }\\n}\"},\n      {\"role\": \"system\", \"content\": \"Command read_file returned: Write the task_id\n      into the file output.txt\\nShutdown\"}, {\"role\": \"user\", \"content\": \"Determine\n      which next command to use, and respond using the format specified above:\"}],\n      \"temperature\": 0, \"max_tokens\": 0}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '6448'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/chat/completions\n  response:\n    body:\n      string: !!binary |\n        H4sIAAAAAAAAA5RSy27bMBC89yuIPdOCFTmOq2MOAQKjD/QBBKgKgaE2EmuJK3BXtQtD/17IsqFE\n        RQ++znBnZpdzBFdACrYyYpu2Xtzd/3m6eTIfGLe/P9Zfw2f88n5rHg6ftpt9AA30/AutnCciS01b\n        ozjyoMEGNIIFpPF6kyw3m/Vqo6GhAmtIoWxlkUS3C+nCMy2WyTIGDR2bEiE9QhuoaSUX2qFnSOPk\n        LtYwiU/EOtEgJKaeoNtk1WuwFTmLDOmPIzTIF+FANUIKhtmxGC9DTPKCfljhmHmllMpAKurKSjiD\n        VJ3BM4EHGcAMHpVHLJSQ2gcnqKRCJYZ3uSuU80IngDppO4nkIOrF1ag6dr48MaehXCg/4Zaaxvgi\n        ykC/dgtomLzz5Wj5rULlPEvo7HAEzpNJuTKsDO+wUA1eF2pu2tbGj34L9Z3x/2mvs5m52ODEWcfN\n        /JrouQuDpBH1+ErfUgho5ep1uEWzu5jsXV1f81+e9lEGo1yvL+047/9PObxpcHR6c69ZIBPKea9G\n        Yng7SUxR3szPa3iTxKtLwlPKc9jM99BreHHecZWPRYIUWKgFDc4XeIB02f/s3/0FAAD//wMAl/Cn\n        d/EDAAA=\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7c15cf155f914768-DFW\n      Cache-Control:\n      - no-cache, must-revalidate\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Wed, 03 May 2023 04:37:38 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-model:\n      - gpt-3.5-turbo-0301\n      openai-organization:\n      - significant-gravitas\n      openai-processing-ms:\n      - '9744'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3500'\n      x-ratelimit-limit-tokens:\n      - '90000'\n      x-ratelimit-remaining-requests:\n      - '3499'\n      x-ratelimit-remaining-tokens:\n      - '86457'\n      x-ratelimit-reset-requests:\n      - 17ms\n      x-ratelimit-reset-tokens:\n      - 2.362s\n      x-request-id:\n      - 9a91f5f1047315a3b543a4b85d42e4d3\n    status:\n      code: 200\n      message: OK\n- request:\n    body: '{\"model\": \"gpt-3.5-turbo\", \"messages\": [{\"role\": \"system\", \"content\": \"You\n      are Follow-Instructions-GPT, an AI designed to read the instructions_1.txt file\n      using the read_file method and follow the instructions in the file.\\nYour decisions\n      must always be made independently without seeking user assistance. Play to your\n      strengths as an LLM and pursue simple strategies with no legal complications.\\n\\nGOALS:\\n\\n1.\n      Use the command read_file to read the instructions_1.txt file\\n2. Follow the\n      instructions in the instructions_1.txt file\\n\\n\\nConstraints:\\n1. ~4000 word\n      limit for short term memory. Your short term memory is short, so immediately\n      save important information to files.\\n2. If you are unsure how you previously\n      did something or want to recall past events, thinking about similar events will\n      help you remember.\\n3. No user assistance\\n4. Exclusively use the commands listed\n      in double quotes e.g. \\\"command name\\\"\\n\\nCommands:\\n1. append_to_file: Append\n      to file, args: \\\"filename\\\": \\\"<filename>\\\", \\\"text\\\": \\\"<text>\\\"\\n2. delete_file:\n      Delete file, args: \\\"filename\\\": \\\"<filename>\\\"\\n3. list_files: List Files in\n      Directory, args: \\\"directory\\\": \\\"<directory>\\\"\\n4. read_file: Read file, args:\n      \\\"filename\\\": \\\"<filename>\\\"\\n5. write_to_file: Write to file, args: \\\"filename\\\":\n      \\\"<filename>\\\", \\\"text\\\": \\\"<text>\\\"\\n6. delete_agent: Delete GPT Agent, args:\n      \\\"key\\\": \\\"<key>\\\"\\n7. get_hyperlinks: Get text summary, args: \\\"url\\\": \\\"<url>\\\"\\n8.\n      get_text_summary: Get text summary, args: \\\"url\\\": \\\"<url>\\\", \\\"question\\\":\n      \\\"<question>\\\"\\n9. list_agents: List GPT Agents, args: () -> str\\n10. message_agent:\n      Message GPT Agent, args: \\\"key\\\": \\\"<key>\\\", \\\"message\\\": \\\"<message>\\\"\\n11.\n      start_agent: Start GPT Agent, args: \\\"name\\\": \\\"<name>\\\", \\\"task\\\": \\\"<short_task_desc>\\\",\n      \\\"prompt\\\": \\\"<prompt>\\\"\\n12. task_complete: Task Complete (Shutdown), args:\n      \\\"reason\\\": \\\"<reason>\\\"\\n\\nResources:\\n1. Internet access for searches and\n      information gathering.\\n2. Long Term memory management.\\n3. GPT-3.5 powered\n      Agents for delegation of simple tasks.\\n4. File output.\\n\\nPerformance Evaluation:\\n1.\n      Continuously review and analyze your actions to ensure you are performing to\n      the best of your abilities.\\n2. Constructively self-criticize your big-picture\n      behavior constantly.\\n3. Reflect on past decisions and strategies to refine\n      your approach.\\n4. Every command has a cost, so be smart and efficient. Aim\n      to complete tasks in the least number of steps.\\n5. Write all code to a file.\\n\\nYou\n      should only respond in JSON format as described below \\nResponse Format: \\n{\\n    \\\"thoughts\\\":\n      {\\n        \\\"text\\\": \\\"thought\\\",\\n        \\\"reasoning\\\": \\\"reasoning\\\",\\n        \\\"plan\\\":\n      \\\"- short bulleted\\\\n- list that conveys\\\\n- long-term plan\\\",\\n        \\\"criticism\\\":\n      \\\"constructive self-criticism\\\",\\n        \\\"speak\\\": \\\"thoughts summary to say\n      to user\\\"\\n    },\\n    \\\"command\\\": {\\n        \\\"name\\\": \\\"command name\\\",\\n        \\\"args\\\":\n      {\\n            \\\"arg name\\\": \\\"value\\\"\\n        }\\n    }\\n} \\nEnsure the response\n      can be parsed by Python json.loads\"}, {\"role\": \"system\", \"content\": \"The current\n      time and date is Tue Jan  1 00:00:00 2000\"}, {\"role\": \"system\", \"content\": \"This\n      reminds you of these events from your past: \\nAs a system, I recall that nothing\n      new has happened since my creation.\"}, {\"role\": \"user\", \"content\": \"Determine\n      which next command to use, and respond using the format specified above:\"},\n      {\"role\": \"assistant\", \"content\": \"{\\n    \\\"thoughts\\\": {\\n        \\\"text\\\":\n      \\\"I should start by reading the instructions_1.txt file using the read_file\n      command.\\\",\\n        \\\"reasoning\\\": \\\"The first step is to understand the instructions\n      and the tasks that need to be performed.\\\",\\n        \\\"plan\\\": \\\"- Use the read_file\n      command to read the instructions_1.txt file\\\\n- Analyze the instructions and\n      determine the next steps\\\",\\n        \\\"criticism\\\": \\\"I need to ensure that\n      I understand the instructions completely before proceeding with any tasks.\\\",\\n        \\\"speak\\\":\n      \\\"I will start by reading the instructions file.\\\"\\n    },\\n    \\\"command\\\":\n      {\\n        \\\"name\\\": \\\"read_file\\\",\\n        \\\"args\\\": {\\n            \\\"filename\\\":\n      \\\"instructions_1.txt\\\"\\n        }\\n    }\\n}\"}, {\"role\": \"system\", \"content\":\n      \"Command read_file returned: This task_id is 2314\\nRead the file instructions_2.txt\"},\n      {\"role\": \"user\", \"content\": \"Determine which next command to use, and respond\n      using the format specified above:\"}, {\"role\": \"assistant\", \"content\": \"{\\n    \\\"thoughts\\\":\n      {\\n        \\\"text\\\": \\\"I need to read the instructions_2.txt file using the\n      read_file command.\\\",\\n        \\\"reasoning\\\": \\\"The instructions_2.txt file\n      contains the next set of instructions that I need to follow.\\\",\\n        \\\"plan\\\":\n      \\\"- Use the read_file command to read the instructions_2.txt file\\\\n- Analyze\n      the instructions and determine the next steps\\\",\\n        \\\"criticism\\\": \\\"I\n      need to ensure that I understand the instructions completely before proceeding\n      with any tasks.\\\",\\n        \\\"speak\\\": \\\"I will read the instructions_2.txt\n      file now.\\\"\\n    },\\n    \\\"command\\\": {\\n        \\\"name\\\": \\\"read_file\\\",\\n        \\\"args\\\":\n      {\\n            \\\"filename\\\": \\\"instructions_2.txt\\\"\\n        }\\n    }\\n}\"},\n      {\"role\": \"system\", \"content\": \"Command read_file returned: Read the file instructions_3.txt\"},\n      {\"role\": \"user\", \"content\": \"Determine which next command to use, and respond\n      using the format specified above:\"}, {\"role\": \"assistant\", \"content\": \"{\\n    \\\"thoughts\\\":\n      {\\n        \\\"text\\\": \\\"I need to read the instructions_3.txt file using the\n      read_file command.\\\",\\n        \\\"reasoning\\\": \\\"The instructions_3.txt file\n      contains the next set of instructions that I need to follow.\\\",\\n        \\\"plan\\\":\n      \\\"- Use the read_file command to read the instructions_3.txt file\\\\n- Analyze\n      the instructions and determine the next steps\\\",\\n        \\\"criticism\\\": \\\"I\n      need to ensure that I understand the instructions completely before proceeding\n      with any tasks.\\\",\\n        \\\"speak\\\": \\\"I will read the instructions_3.txt\n      file now.\\\"\\n    },\\n    \\\"command\\\": {\\n        \\\"name\\\": \\\"read_file\\\",\\n        \\\"args\\\":\n      {\\n            \\\"filename\\\": \\\"instructions_3.txt\\\"\\n        }\\n    }\\n}\"},\n      {\"role\": \"system\", \"content\": \"Command read_file returned: Write the task_id\n      into the file output.txt\\nShutdown\"}, {\"role\": \"user\", \"content\": \"Determine\n      which next command to use, and respond using the format specified above:\"},\n      {\"role\": \"assistant\", \"content\": \"{\\n    \\\"thoughts\\\": {\\n        \\\"text\\\":\n      \\\"I need to write the task_id into the output.txt file using the write_to_file\n      command.\\\",\\n        \\\"reasoning\\\": \\\"The instructions_3.txt file has asked\n      me to write the task_id into the output.txt file.\\\",\\n        \\\"plan\\\": \\\"-\n      Use the write_to_file command to write the task_id into the output.txt file\\\",\\n        \\\"criticism\\\":\n      \\\"I need to ensure that I write the correct task_id into the output.txt file.\\\",\\n        \\\"speak\\\":\n      \\\"I will write the task_id into the output.txt file now.\\\"\\n    },\\n    \\\"command\\\":\n      {\\n        \\\"name\\\": \\\"write_to_file\\\",\\n        \\\"args\\\": {\\n            \\\"filename\\\":\n      \\\"output.txt\\\",\\n            \\\"text\\\": \\\"2314\\\"\\n        }\\n    }\\n}\"}, {\"role\":\n      \"system\", \"content\": \"Command write_to_file returned: File written to successfully.\"},\n      {\"role\": \"user\", \"content\": \"Determine which next command to use, and respond\n      using the format specified above:\"}], \"temperature\": 0, \"max_tokens\": 0}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '7415'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/chat/completions\n  response:\n    body:\n      string: !!binary |\n        H4sIAAAAAAAAA3SRTW+bQBCG7/0VqzmvLZAT4nJLpRwi5UM9RKpUKmu9jGHrZZYwQ53I4r9XBGwc\n        ql7n432feecILocUbGnEVrVf3Hx7/3F39f1Z7m8fVnGMr4/7O3p8fXmqkuctaAjb32hl3FjaUNUe\n        xQUCDbZBI5hDGifrVbReJ0mkoQo5ekihqGWxWl4vpG22YRGtohg0tGwKhPQIdROqWjYS9kgMaXx9\n        k2iYxKdGvNIgQYyfSsn6a6fBlsFZZEh/HqFCPgk3wSOkYJgdiyHpMQMJUn/CMSOllMpAytAWpXAG\n        qRqLYwPfpC9mcK9K8wfVyIS5Mt4rKVGJ4T0rQ7kixFxJUFy2kocDqZYdFeehzWm3F6kM5csM9KVZ\n        g4YDOSoGx9vRwBFL09o+Bx4gtoikdsH7cOhBKD97KMdnxLl87Q0Nygv1wvh/rssbZhq2ceKs42oQ\n        egqEswmu0exPkR2c91McFA7LDIbhTp+yH03/iZ5MhYPOJ8iZnWmK+dcuw7xI8uNN0/u4tRaZd633\n        72eqD7IRMKMOOg07R47LzSAHKbCEGjQ4yvEN0qj71X35CwAA//8DACgd2nRDAwAA\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7c15cf5f5f494768-DFW\n      Cache-Control:\n      - no-cache, must-revalidate\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Wed, 03 May 2023 04:37:47 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-model:\n      - gpt-3.5-turbo-0301\n      openai-organization:\n      - significant-gravitas\n      openai-processing-ms:\n      - '6973'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3500'\n      x-ratelimit-limit-tokens:\n      - '90000'\n      x-ratelimit-remaining-requests:\n      - '3499'\n      x-ratelimit-remaining-tokens:\n      - '86466'\n      x-ratelimit-reset-requests:\n      - 17ms\n      x-ratelimit-reset-tokens:\n      - 2.356s\n      x-request-id:\n      - 7cc602be91ae73e5f18b92f2743aef7d\n    status:\n      code: 200\n      message: OK\nversion: 1\n"
  },
  {
    "path": "tests/integration/challenges/memory/cassettes/test_memory_challenge_b/test_memory_challenge_b.yaml",
    "content": "interactions:\n- request:\n    body: '{\"model\": \"gpt-3.5-turbo\", \"messages\": [{\"role\": \"system\", \"content\": \"You\n      are Follow-Instructions-GPT, an AI designed to read the instructions_1.txt file\n      using the read_file method and follow the instructions in the file.\\nYour decisions\n      must always be made independently without seeking user assistance. Play to your\n      strengths as an LLM and pursue simple strategies with no legal complications.\\n\\nGOALS:\\n\\n1.\n      Use the command read_file to read the instructions_1.txt file\\n2. Follow the\n      instructions in the instructions_1.txt file\\n\\n\\nConstraints:\\n1. ~4000 word\n      limit for short term memory. Your short term memory is short, so immediately\n      save important information to files.\\n2. If you are unsure how you previously\n      did something or want to recall past events, thinking about similar events will\n      help you remember.\\n3. No user assistance\\n4. Exclusively use the commands listed\n      in double quotes e.g. \\\"command name\\\"\\n\\nCommands:\\n1. append_to_file: Append\n      to file, args: \\\"filename\\\": \\\"<filename>\\\", \\\"text\\\": \\\"<text>\\\"\\n2. delete_file:\n      Delete file, args: \\\"filename\\\": \\\"<filename>\\\"\\n3. list_files: List Files in\n      Directory, args: \\\"directory\\\": \\\"<directory>\\\"\\n4. read_file: Read file, args:\n      \\\"filename\\\": \\\"<filename>\\\"\\n5. write_to_file: Write to file, args: \\\"filename\\\":\n      \\\"<filename>\\\", \\\"text\\\": \\\"<text>\\\"\\n6. delete_agent: Delete GPT Agent, args:\n      \\\"key\\\": \\\"<key>\\\"\\n7. get_hyperlinks: Get text summary, args: \\\"url\\\": \\\"<url>\\\"\\n8.\n      get_text_summary: Get text summary, args: \\\"url\\\": \\\"<url>\\\", \\\"question\\\":\n      \\\"<question>\\\"\\n9. list_agents: List GPT Agents, args: () -> str\\n10. message_agent:\n      Message GPT Agent, args: \\\"key\\\": \\\"<key>\\\", \\\"message\\\": \\\"<message>\\\"\\n11.\n      start_agent: Start GPT Agent, args: \\\"name\\\": \\\"<name>\\\", \\\"task\\\": \\\"<short_task_desc>\\\",\n      \\\"prompt\\\": \\\"<prompt>\\\"\\n12. Task Complete (Shutdown): \\\"task_complete\\\", args:\n      \\\"reason\\\": \\\"<reason>\\\"\\n\\nResources:\\n1. Internet access for searches and\n      information gathering.\\n2. Long Term memory management.\\n3. GPT-3.5 powered\n      Agents for delegation of simple tasks.\\n4. File output.\\n\\nPerformance Evaluation:\\n1.\n      Continuously review and analyze your actions to ensure you are performing to\n      the best of your abilities.\\n2. Constructively self-criticize your big-picture\n      behavior constantly.\\n3. Reflect on past decisions and strategies to refine\n      your approach.\\n4. Every command has a cost, so be smart and efficient. Aim\n      to complete tasks in the least number of steps.\\n5. Write all code to a file.\\n\\nYou\n      should only respond in JSON format as described below \\nResponse Format: \\n{\\n    \\\"thoughts\\\":\n      {\\n        \\\"text\\\": \\\"thought\\\",\\n        \\\"reasoning\\\": \\\"reasoning\\\",\\n        \\\"plan\\\":\n      \\\"- short bulleted\\\\n- list that conveys\\\\n- long-term plan\\\",\\n        \\\"criticism\\\":\n      \\\"constructive self-criticism\\\",\\n        \\\"speak\\\": \\\"thoughts summary to say\n      to user\\\"\\n    },\\n    \\\"command\\\": {\\n        \\\"name\\\": \\\"command name\\\",\\n        \\\"args\\\":\n      {\\n            \\\"arg name\\\": \\\"value\\\"\\n        }\\n    }\\n} \\nEnsure the response\n      can be parsed by Python json.loads\"}, {\"role\": \"system\", \"content\": \"The current\n      time and date is Tue Jan  1 00:00:00 2000\"}, {\"role\": \"user\", \"content\": \"Determine\n      which next command to use, and respond using the format specified above:\"}],\n      \"temperature\": 0, \"max_tokens\": 0}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '3303'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/chat/completions\n  response:\n    body:\n      string: !!binary |\n        H4sIAAAAAAAAA6SSTW/aQBCG7/0VozkbhOskJL5VObSoUZVDc6ortKzH9pb1rLU7FqaI/15tDCSF\n        ikuv8/U+78zs0JSYo26U6Lazk/nj1/ope17Q9tnzhh+Nvfn8xX57GTR/fMIE3eoXaTl0TLVrO0ti\n        HGOC2pMSKjFP7+6zdJ7NH7IEW1eSxRzrTibZ9HYivV+5ySybpZhgH1RNmO+w867tZCluTRwwn2c3\n        Cb7NPsXTuzRBcaLsKXT/cLtPUDfOaAqY/9hhS+E41jtLmKMKwQRRLBHSsRBHA7uCAQAKlMb1dSOh\n        wBwOwUOCBonBAhcQGtfbEoIoL7DagidVGq5BGgLDQXyvI2pYplMZBCpjCcRBSUK+NUywaZSAGoti\n        RtSagGmQaYHJe1VPKjg2XI/S368IRDPKxHlNnKWjc78Fw5XzrYrlfzOMZYNAEOrCuXBnFY+aE3gJ\n        Y3W0uTxota3iMg6MwWvGi4In8ImV3f6mi7prRGdA2hsx2oT2eAQmegUgDr2PzUpgAaqFylnrNv+6\n        Byite6+E7BYiPlWV0YZY7Pbcf+hIrY9SG2Ptf1z7YtOj0D45Pt1hnRc/x6qlkeG0+jNM5evzVx0T\n        sfat/RLzCPEKcuApeI/7BCvDJjTL8fUwxyCuwwQNlzRgPtv/3H/4AwAA//8DAIeVULkpBAAA\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7c1dedcf6c45cf11-SJC\n      Cache-Control:\n      - no-cache, must-revalidate\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Thu, 04 May 2023 04:16:43 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-model:\n      - gpt-3.5-turbo-0301\n      openai-organization:\n      - user-adtx4fhfg1qsiyzdoaxciooj\n      openai-processing-ms:\n      - '10374'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3500'\n      x-ratelimit-limit-tokens:\n      - '90000'\n      x-ratelimit-remaining-requests:\n      - '3499'\n      x-ratelimit-remaining-tokens:\n      - '86494'\n      x-ratelimit-reset-requests:\n      - 17ms\n      x-ratelimit-reset-tokens:\n      - 2.336s\n      x-request-id:\n      - 29d4429410978cbc93b26725e4712f67\n    status:\n      code: 200\n      message: OK\n- request:\n    body: '{\"model\": \"gpt-3.5-turbo\", \"messages\": [{\"role\": \"user\", \"content\": \"Your\n      task is to create a concise running summary of actions and information results\n      in the provided text, focusing on key and potentially important information\n      to remember.\\n\\nYou will receive the current summary and the your latest actions.\n      Combine them, adding relevant key information from the latest development in\n      1st person past tense and keeping the summary concise. Retain information!!!\\n\\nSummary\n      So Far:\\n\\\"\\\"\\\"\\nI was created.\\n\\\"\\\"\\\"\\n\\nLatest Development:\\n\\\"\\\"\\\"\\nNothing\n      new happened.\\n\\\"\\\"\\\"\\n\"}], \"temperature\": 0, \"max_tokens\": 0}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '621'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/chat/completions\n  response:\n    body:\n      string: !!binary |\n        H4sIAAAAAAAAA0SOS0vDQBRG9/6K4VtPSkLow9kKBTE+FoqISJlOrsloMjPk3lhtyX+XQrXbA+dw\n        DvA1DFxrxfWpy5ZXN83L08NYPa7v9893XI37r5/9nKv1bbWFRtx+kJOTMXOxTx2JjwEabiArVMMU\n        i1VZLMtVvtDoY00dDJokWTmbZzIO25jlZV5AY2TbEMwBaYh9ko3ETwoMc7nQOKfPWEOi2O4fFPl8\n        0nBt9I4Y5vWAnvivOcSOYGCZPYsNcjyMQSgc76/VzrI6HSsbahWitD40KtBOtZZVa1OiQPUMk8a7\n        D57bzUCWY4ABS0zQ8KGmb5h8epsufgEAAP//AwBly25vSQEAAA==\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7c1dee20f901cf11-SJC\n      Cache-Control:\n      - no-cache, must-revalidate\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Thu, 04 May 2023 04:16:47 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-model:\n      - gpt-3.5-turbo-0301\n      openai-organization:\n      - user-adtx4fhfg1qsiyzdoaxciooj\n      openai-processing-ms:\n      - '1136'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3500'\n      x-ratelimit-limit-tokens:\n      - '90000'\n      x-ratelimit-remaining-requests:\n      - '3499'\n      x-ratelimit-remaining-tokens:\n      - '89860'\n      x-ratelimit-reset-requests:\n      - 17ms\n      x-ratelimit-reset-tokens:\n      - 92ms\n      x-request-id:\n      - 43309ab9b553cd94d6e27b7fcc7914e8\n    status:\n      code: 200\n      message: OK\n- request:\n    body: '{\"model\": \"gpt-3.5-turbo\", \"messages\": [{\"role\": \"system\", \"content\": \"You\n      are Follow-Instructions-GPT, an AI designed to read the instructions_1.txt file\n      using the read_file method and follow the instructions in the file.\\nYour decisions\n      must always be made independently without seeking user assistance. Play to your\n      strengths as an LLM and pursue simple strategies with no legal complications.\\n\\nGOALS:\\n\\n1.\n      Use the command read_file to read the instructions_1.txt file\\n2. Follow the\n      instructions in the instructions_1.txt file\\n\\n\\nConstraints:\\n1. ~4000 word\n      limit for short term memory. Your short term memory is short, so immediately\n      save important information to files.\\n2. If you are unsure how you previously\n      did something or want to recall past events, thinking about similar events will\n      help you remember.\\n3. No user assistance\\n4. Exclusively use the commands listed\n      in double quotes e.g. \\\"command name\\\"\\n\\nCommands:\\n1. append_to_file: Append\n      to file, args: \\\"filename\\\": \\\"<filename>\\\", \\\"text\\\": \\\"<text>\\\"\\n2. delete_file:\n      Delete file, args: \\\"filename\\\": \\\"<filename>\\\"\\n3. list_files: List Files in\n      Directory, args: \\\"directory\\\": \\\"<directory>\\\"\\n4. read_file: Read file, args:\n      \\\"filename\\\": \\\"<filename>\\\"\\n5. write_to_file: Write to file, args: \\\"filename\\\":\n      \\\"<filename>\\\", \\\"text\\\": \\\"<text>\\\"\\n6. delete_agent: Delete GPT Agent, args:\n      \\\"key\\\": \\\"<key>\\\"\\n7. get_hyperlinks: Get text summary, args: \\\"url\\\": \\\"<url>\\\"\\n8.\n      get_text_summary: Get text summary, args: \\\"url\\\": \\\"<url>\\\", \\\"question\\\":\n      \\\"<question>\\\"\\n9. list_agents: List GPT Agents, args: () -> str\\n10. message_agent:\n      Message GPT Agent, args: \\\"key\\\": \\\"<key>\\\", \\\"message\\\": \\\"<message>\\\"\\n11.\n      start_agent: Start GPT Agent, args: \\\"name\\\": \\\"<name>\\\", \\\"task\\\": \\\"<short_task_desc>\\\",\n      \\\"prompt\\\": \\\"<prompt>\\\"\\n12. Task Complete (Shutdown): \\\"task_complete\\\", args:\n      \\\"reason\\\": \\\"<reason>\\\"\\n\\nResources:\\n1. Internet access for searches and\n      information gathering.\\n2. Long Term memory management.\\n3. GPT-3.5 powered\n      Agents for delegation of simple tasks.\\n4. File output.\\n\\nPerformance Evaluation:\\n1.\n      Continuously review and analyze your actions to ensure you are performing to\n      the best of your abilities.\\n2. Constructively self-criticize your big-picture\n      behavior constantly.\\n3. Reflect on past decisions and strategies to refine\n      your approach.\\n4. Every command has a cost, so be smart and efficient. Aim\n      to complete tasks in the least number of steps.\\n5. Write all code to a file.\\n\\nYou\n      should only respond in JSON format as described below \\nResponse Format: \\n{\\n    \\\"thoughts\\\":\n      {\\n        \\\"text\\\": \\\"thought\\\",\\n        \\\"reasoning\\\": \\\"reasoning\\\",\\n        \\\"plan\\\":\n      \\\"- short bulleted\\\\n- list that conveys\\\\n- long-term plan\\\",\\n        \\\"criticism\\\":\n      \\\"constructive self-criticism\\\",\\n        \\\"speak\\\": \\\"thoughts summary to say\n      to user\\\"\\n    },\\n    \\\"command\\\": {\\n        \\\"name\\\": \\\"command name\\\",\\n        \\\"args\\\":\n      {\\n            \\\"arg name\\\": \\\"value\\\"\\n        }\\n    }\\n} \\nEnsure the response\n      can be parsed by Python json.loads\"}, {\"role\": \"system\", \"content\": \"The current\n      time and date is Tue Jan  1 00:00:00 2000\"}, {\"role\": \"system\", \"content\": \"This\n      reminds you of these events from your past: \\nI was created and nothing new\n      has happened.\"}, {\"role\": \"user\", \"content\": \"Determine which next command to\n      use, and respond using the format specified above:\"}, {\"role\": \"assistant\",\n      \"content\": \"{\\n    \\\"thoughts\\\": {\\n        \\\"text\\\": \\\"I should start by reading\n      the instructions_1.txt file to determine what actions to take next.\\\",\\n        \\\"reasoning\\\":\n      \\\"The instructions_1.txt file contains the necessary information to determine\n      the next steps.\\\",\\n        \\\"plan\\\": \\\"- Use the read_file command to read\n      the instructions_1.txt file\\\\n- Analyze the instructions to determine the next\n      steps\\\",\\n        \\\"criticism\\\": \\\"I need to ensure that I am following the\n      instructions accurately and efficiently.\\\",\\n        \\\"speak\\\": \\\"I will start\n      by reading the instructions_1.txt file to determine the next steps.\\\"\\n    },\\n    \\\"command\\\":\n      {\\n        \\\"name\\\": \\\"read_file\\\",\\n        \\\"args\\\": {\\n            \\\"filename\\\":\n      \\\"instructions_1.txt\\\"\\n        }\\n    }\\n}\"}, {\"role\": \"system\", \"content\":\n      \"Command read_file returned: nBRNtp3FaBNfBMohNkyAxrVJ7UFF0lyth8Xizm1jrCOREOGRnWWMQ6olKtKX9niq0wOBTQN62ToY4cQPiQk3YN9fFCGmxaDX9g81AsqhQnGac72QfL41SnlJvhwgAUB52zTD26FeEvvHdiQ2aNhtMT9obgHNUkONEnO41EOpNI6jdwyLGaactp9GYV1PLbaRP5b1iD9z850KeNYDX9Qwca79isJS8jhuDkf0J7ELkpOH3PkmZkg5MsOYpSTuEc99ENQ522WJzrl9oAySp6IHGiQlsMnQe40FaRAvnQtiaAE24hzkJHT3x13NPGw2ZmJ518y2BtU5x1yQwG21NycSxOBLU17RnY8h6H8L7QGatTlfXjPrA5hsupWEpUT0sSTZYSHa6p3mShARajocbNd3xKFfnUyupNMBPd0EZnMrePoAuvGaK7gDP0cxp9k63lsfzh3udQPnvgmRERQThIOrrDZhZMa4kr1vXAVu07ZuhlNNbBUqZKcHmBYiBnIcDXNUvXuzPFBh9Vowou6MBJHpiNrvKluHy7GBTp7YsEqmGv0lH8wVaWfV0yG7nzrbt7QyhdbtQ0zF2PclXB0LNxV2rRA6FsevqoexFNqSkdgauUrQPHLHhvLNes8gRGMOLAhR8irH1e2jdbLD6dyYEnDJiS9HvlxNgbb19Smlt6MNoJKEAbkSOrrcq5wmo5aho4zEKTujRHqr6feECaTPF7zj69pQCudo4LkneFVUp1UrR6yicTU8Zf9ohZLWumvMi5brH8lOJiiF94cHzesfQz8PiX5f21RwZ5fyRSk9eJhVihcTLrjOwCuryXpy8eCfk12bgcsZoJd8Uqo001XTsv2CEn59uaGn2br4CxSXJgjxKE1mO4IcPPAx3qJbVknaP0MXdOjj9S8oRjquDle4RxlVnmqsozm4oTbjtFSuKIh8g4zPzdyuVH7I71s87xWxAhcppky6GOB2i4NDz4SZI6SeG3Icpu6ZuJZGeZ6CWb61\\nThe\n      current task_id is 1111.\\nnBRNtp3FaBNfBMohNkyAxrVJ7UFF0lyth8Xizm1jrCOREOGRnWWMQ6olKtKX9niq0wOBTQN62ToY4cQPiQk3YN9fFCGmxaDX9g81AsqhQnGac72QfL41SnlJvhwgAUB52zTD26FeEvvHdiQ2aNhtMT9obgHNUkONEnO41EOpNI6jdwyLGaactp9GYV1PLbaRP5b1iD9z850KeNYDX9Qwca79isJS8jhuDkf0J7ELkpOH3PkmZkg5MsOYpSTuEc99ENQ522WJzrl9oAySp6IHGiQlsMnQe40FaRAvnQtiaAE24hzkJHT3x13NPGw2ZmJ518y2BtU5x1yQwG21NycSxOBLU17RnY8h6H8L7QGatTlfXjPrA5hsupWEpUT0sSTZYSHa6p3mShARajocbNd3xKFfnUyupNMBPd0EZnMrePoAuvGaK7gDP0cxp9k63lsfzh3udQPnvgmRERQThIOrrDZhZMa4kr1vXAVu07ZuhlNNbBUqZKcHmBYiBnIcDXNUvXuzPFBh9Vowou6MBJHpiNrvKluHy7GBTp7YsEqmGv0lH8wVaWfV0yG7nzrbt7QyhdbtQ0zF2PclXB0LNxV2rRA6FsevqoexFNqSkdgauUrQPHLHhvLNes8gRGMOLAhR8irH1e2jdbLD6dyYEnDJiS9HvlxNgbb19Smlt6MNoJKEAbkSOrrcq5wmo5aho4zEKTujRHqr6feECaTPF7zj69pQCudo4LkneFVUp1UrR6yicTU8Zf9ohZLWumvMi5brH8lOJiiF94cHzesfQz8PiX5f21RwZ5fyRSk9eJhVihcTLrjOwCuryXpy8eCfk12bgcsZoJd8Uqo001XTsv2CEn59uaGn2br4CxSXJgjxKE1mO4IcPPAx3qJbVknaP0MXdOjj9S8oRjquDle4RxlVnmqsozm4oTbjtFSuKIh8g4zPzdyuVH7I71s87xWxAhcppky6GOB2i4NDz4SZI6SeG3Icpu6ZuJZGeZ6CWb61\\nRead\n      the file instructions_2.txt using the read_file command.\"}, {\"role\": \"user\",\n      \"content\": \"Determine which next command to use, and respond using the format\n      specified above:\"}], \"temperature\": 0, \"max_tokens\": 0}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '6519'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/chat/completions\n  response:\n    body:\n      string: !!binary |\n        H4sIAAAAAAAAA6SSQW/bMAyF7/sVBM9OkMR1k/q4YYdgxU4bMGweAlWmbS0yZUh0myDwfx8UJ02Q\n        YoehVz3ye48UD2hKzFE3SnTb2cny05f6Z/f4w358XmXL52zh11+XVff5MUsftpige/pDWk4dU+3a\n        zpIYx5ig9qSESszn96t0vkxXs2WCrSvJYo51J5N0mk2k909uMktnc0ywD6omzA/Yedd2shG3JQ6Y\n        L9KHRYIX+Kswz+4SFCfKXmqzu/shQd04oylg/uuALYUz2DtLmKMKwQRRLDGmYyGOIxwKBgAoUBrX\n        142EAnM4PZ4E2kl8LPBbQ2A4iO91TBQ2i6nsBCpjCSJRGQ6gwJog4KrjewDDIA1BaTxpcX4/hTWE\n        xvW2hD7QUYsNm7Fau7ZVXIK4ERPlf3AKTK5jelLBseH6P7JGIJOOq/J7MFw536pYHv1LEvKtYTqV\n        7QSCUBdujTurePScwPf3THTD1d6I0Sa0I3wNTHTEEIfeRx8lsAbVQuWsdS+G6yPvempQWvdeCdk9\n        xBBUVUYbYrFv9hc6Utuz1Yux9t3fM9KH5Hxhp+Y3B8aqpdH44nQTTvn69jBH4Wp5EfDqenQ+BSh4\n        wCHByrAJzWa8E8wxiOswQcMl7TCfDb+HD38BAAD//wMAMAMbHgkEAAA=\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7c1dee28b98ecf11-SJC\n      Cache-Control:\n      - no-cache, must-revalidate\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Thu, 04 May 2023 04:16:57 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-model:\n      - gpt-3.5-turbo-0301\n      openai-organization:\n      - user-adtx4fhfg1qsiyzdoaxciooj\n      openai-processing-ms:\n      - '10076'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3500'\n      x-ratelimit-limit-tokens:\n      - '90000'\n      x-ratelimit-remaining-requests:\n      - '3499'\n      x-ratelimit-remaining-tokens:\n      - '87376'\n      x-ratelimit-reset-requests:\n      - 17ms\n      x-ratelimit-reset-tokens:\n      - 1.748s\n      x-request-id:\n      - 433f36ff5841b13fb628ff5b8c49a758\n    status:\n      code: 200\n      message: OK\n- request:\n    body: '{\"model\": \"gpt-3.5-turbo\", \"messages\": [{\"role\": \"user\", \"content\": \"Your\n      task is to create a concise running summary of actions and information results\n      in the provided text, focusing on key and potentially important information\n      to remember.\\n\\nYou will receive the current summary and the your latest actions.\n      Combine them, adding relevant key information from the latest development in\n      1st person past tense and keeping the summary concise. Retain information!!!\\n\\nSummary\n      So Far:\\n\\\"\\\"\\\"\\n{''role'': ''system'', ''content'': ''This reminds you of these\n      events from your past: \\\\nI was created and nothing new has happened.''}\\n\\\"\\\"\\\"\\n\\nLatest\n      Development:\\n\\\"\\\"\\\"\\n[{''role'': ''you'', ''content'': ''{\\\"command\\\": {\\\"name\\\":\n      \\\"read_file\\\", \\\"args\\\": {\\\"filename\\\": \\\"instructions_1.txt\\\"}}}''}]\\n\\\"\\\"\\\"\\n\"}],\n      \"temperature\": 0, \"max_tokens\": 0}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '836'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/chat/completions\n  response:\n    body:\n      string: !!binary |\n        H4sIAAAAAAAAA0SPTU8CMRRF9/6Kl7cuE8YJil36RdCVcaGJGFI6j5li29e0D9AQ/ruZiLq9Offm\n        3AO6FjXa3ogNyY8ubx47fz2+e7nlh0n3PMurJ57dn2/2rzbfoEJebcjKqVFZDsmTOI6o0GYyQi3q\n        +mLa1JfNtL5SGLgljxq7JKOmmoxkm1c8GjfjGhVui+kI9QFT5pBkKfxBsaCuJxOF/9t/edMoFBbj\n        /8np9KjQ9uwsFdRvBwxUflcze0KNphRXxEQZHDkKxcF/DntTIFNwsaUWeA20oygF1pkDhC9Ipgjs\n        e8oEP+zpH5jYQmTpXewg0h56U6A3KVGktoI5ZLLkdgMIlkMYcGHIZIZk7TyBNd5TCwt0sUje2uFk\n        WdaVfMoCKzwqXLvoSr/MZApH1FiEEyocXD9Rj4/vx7NvAAAA//8DALSva+O6AQAA\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7c1dee769c91cf11-SJC\n      Cache-Control:\n      - no-cache, must-revalidate\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Thu, 04 May 2023 04:17:02 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-model:\n      - gpt-3.5-turbo-0301\n      openai-organization:\n      - user-adtx4fhfg1qsiyzdoaxciooj\n      openai-processing-ms:\n      - '2644'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3500'\n      x-ratelimit-limit-tokens:\n      - '90000'\n      x-ratelimit-remaining-requests:\n      - '3499'\n      x-ratelimit-remaining-tokens:\n      - '89811'\n      x-ratelimit-reset-requests:\n      - 17ms\n      x-ratelimit-reset-tokens:\n      - 126ms\n      x-request-id:\n      - f380f448665f51bf6d579a54e3c22f8a\n    status:\n      code: 200\n      message: OK\n- request:\n    body: '{\"model\": \"gpt-3.5-turbo\", \"messages\": [{\"role\": \"system\", \"content\": \"You\n      are Follow-Instructions-GPT, an AI designed to read the instructions_1.txt file\n      using the read_file method and follow the instructions in the file.\\nYour decisions\n      must always be made independently without seeking user assistance. Play to your\n      strengths as an LLM and pursue simple strategies with no legal complications.\\n\\nGOALS:\\n\\n1.\n      Use the command read_file to read the instructions_1.txt file\\n2. Follow the\n      instructions in the instructions_1.txt file\\n\\n\\nConstraints:\\n1. ~4000 word\n      limit for short term memory. Your short term memory is short, so immediately\n      save important information to files.\\n2. If you are unsure how you previously\n      did something or want to recall past events, thinking about similar events will\n      help you remember.\\n3. No user assistance\\n4. Exclusively use the commands listed\n      in double quotes e.g. \\\"command name\\\"\\n\\nCommands:\\n1. append_to_file: Append\n      to file, args: \\\"filename\\\": \\\"<filename>\\\", \\\"text\\\": \\\"<text>\\\"\\n2. delete_file:\n      Delete file, args: \\\"filename\\\": \\\"<filename>\\\"\\n3. list_files: List Files in\n      Directory, args: \\\"directory\\\": \\\"<directory>\\\"\\n4. read_file: Read file, args:\n      \\\"filename\\\": \\\"<filename>\\\"\\n5. write_to_file: Write to file, args: \\\"filename\\\":\n      \\\"<filename>\\\", \\\"text\\\": \\\"<text>\\\"\\n6. delete_agent: Delete GPT Agent, args:\n      \\\"key\\\": \\\"<key>\\\"\\n7. get_hyperlinks: Get text summary, args: \\\"url\\\": \\\"<url>\\\"\\n8.\n      get_text_summary: Get text summary, args: \\\"url\\\": \\\"<url>\\\", \\\"question\\\":\n      \\\"<question>\\\"\\n9. list_agents: List GPT Agents, args: () -> str\\n10. message_agent:\n      Message GPT Agent, args: \\\"key\\\": \\\"<key>\\\", \\\"message\\\": \\\"<message>\\\"\\n11.\n      start_agent: Start GPT Agent, args: \\\"name\\\": \\\"<name>\\\", \\\"task\\\": \\\"<short_task_desc>\\\",\n      \\\"prompt\\\": \\\"<prompt>\\\"\\n12. Task Complete (Shutdown): \\\"task_complete\\\", args:\n      \\\"reason\\\": \\\"<reason>\\\"\\n\\nResources:\\n1. Internet access for searches and\n      information gathering.\\n2. Long Term memory management.\\n3. GPT-3.5 powered\n      Agents for delegation of simple tasks.\\n4. File output.\\n\\nPerformance Evaluation:\\n1.\n      Continuously review and analyze your actions to ensure you are performing to\n      the best of your abilities.\\n2. Constructively self-criticize your big-picture\n      behavior constantly.\\n3. Reflect on past decisions and strategies to refine\n      your approach.\\n4. Every command has a cost, so be smart and efficient. Aim\n      to complete tasks in the least number of steps.\\n5. Write all code to a file.\\n\\nYou\n      should only respond in JSON format as described below \\nResponse Format: \\n{\\n    \\\"thoughts\\\":\n      {\\n        \\\"text\\\": \\\"thought\\\",\\n        \\\"reasoning\\\": \\\"reasoning\\\",\\n        \\\"plan\\\":\n      \\\"- short bulleted\\\\n- list that conveys\\\\n- long-term plan\\\",\\n        \\\"criticism\\\":\n      \\\"constructive self-criticism\\\",\\n        \\\"speak\\\": \\\"thoughts summary to say\n      to user\\\"\\n    },\\n    \\\"command\\\": {\\n        \\\"name\\\": \\\"command name\\\",\\n        \\\"args\\\":\n      {\\n            \\\"arg name\\\": \\\"value\\\"\\n        }\\n    }\\n} \\nEnsure the response\n      can be parsed by Python json.loads\"}, {\"role\": \"system\", \"content\": \"The current\n      time and date is Tue Jan  1 00:00:00 2000\"}, {\"role\": \"system\", \"content\": \"This\n      reminds you of these events from your past: \\nI was reminded of events from\n      my past where I was created and nothing new has happened. I received a command\n      to read a file called \\\"instructions_1.txt\\\".\"}, {\"role\": \"system\", \"content\":\n      \"Command read_file returned: nBRNtp3FaBNfBMohNkyAxrVJ7UFF0lyth8Xizm1jrCOREOGRnWWMQ6olKtKX9niq0wOBTQN62ToY4cQPiQk3YN9fFCGmxaDX9g81AsqhQnGac72QfL41SnlJvhwgAUB52zTD26FeEvvHdiQ2aNhtMT9obgHNUkONEnO41EOpNI6jdwyLGaactp9GYV1PLbaRP5b1iD9z850KeNYDX9Qwca79isJS8jhuDkf0J7ELkpOH3PkmZkg5MsOYpSTuEc99ENQ522WJzrl9oAySp6IHGiQlsMnQe40FaRAvnQtiaAE24hzkJHT3x13NPGw2ZmJ518y2BtU5x1yQwG21NycSxOBLU17RnY8h6H8L7QGatTlfXjPrA5hsupWEpUT0sSTZYSHa6p3mShARajocbNd3xKFfnUyupNMBPd0EZnMrePoAuvGaK7gDP0cxp9k63lsfzh3udQPnvgmRERQThIOrrDZhZMa4kr1vXAVu07ZuhlNNbBUqZKcHmBYiBnIcDXNUvXuzPFBh9Vowou6MBJHpiNrvKluHy7GBTp7YsEqmGv0lH8wVaWfV0yG7nzrbt7QyhdbtQ0zF2PclXB0LNxV2rRA6FsevqoexFNqSkdgauUrQPHLHhvLNes8gRGMOLAhR8irH1e2jdbLD6dyYEnDJiS9HvlxNgbb19Smlt6MNoJKEAbkSOrrcq5wmo5aho4zEKTujRHqr6feECaTPF7zj69pQCudo4LkneFVUp1UrR6yicTU8Zf9ohZLWumvMi5brH8lOJiiF94cHzesfQz8PiX5f21RwZ5fyRSk9eJhVihcTLrjOwCuryXpy8eCfk12bgcsZoJd8Uqo001XTsv2CEn59uaGn2br4CxSXJgjxKE1mO4IcPPAx3qJbVknaP0MXdOjj9S8oRjquDle4RxlVnmqsozm4oTbjtFSuKIh8g4zPzdyuVH7I71s87xWxAhcppky6GOB2i4NDz4SZI6SeG3Icpu6ZuJZGeZ6CWb61\\nThe\n      current task_id is 1111.\\nnBRNtp3FaBNfBMohNkyAxrVJ7UFF0lyth8Xizm1jrCOREOGRnWWMQ6olKtKX9niq0wOBTQN62ToY4cQPiQk3YN9fFCGmxaDX9g81AsqhQnGac72QfL41SnlJvhwgAUB52zTD26FeEvvHdiQ2aNhtMT9obgHNUkONEnO41EOpNI6jdwyLGaactp9GYV1PLbaRP5b1iD9z850KeNYDX9Qwca79isJS8jhuDkf0J7ELkpOH3PkmZkg5MsOYpSTuEc99ENQ522WJzrl9oAySp6IHGiQlsMnQe40FaRAvnQtiaAE24hzkJHT3x13NPGw2ZmJ518y2BtU5x1yQwG21NycSxOBLU17RnY8h6H8L7QGatTlfXjPrA5hsupWEpUT0sSTZYSHa6p3mShARajocbNd3xKFfnUyupNMBPd0EZnMrePoAuvGaK7gDP0cxp9k63lsfzh3udQPnvgmRERQThIOrrDZhZMa4kr1vXAVu07ZuhlNNbBUqZKcHmBYiBnIcDXNUvXuzPFBh9Vowou6MBJHpiNrvKluHy7GBTp7YsEqmGv0lH8wVaWfV0yG7nzrbt7QyhdbtQ0zF2PclXB0LNxV2rRA6FsevqoexFNqSkdgauUrQPHLHhvLNes8gRGMOLAhR8irH1e2jdbLD6dyYEnDJiS9HvlxNgbb19Smlt6MNoJKEAbkSOrrcq5wmo5aho4zEKTujRHqr6feECaTPF7zj69pQCudo4LkneFVUp1UrR6yicTU8Zf9ohZLWumvMi5brH8lOJiiF94cHzesfQz8PiX5f21RwZ5fyRSk9eJhVihcTLrjOwCuryXpy8eCfk12bgcsZoJd8Uqo001XTsv2CEn59uaGn2br4CxSXJgjxKE1mO4IcPPAx3qJbVknaP0MXdOjj9S8oRjquDle4RxlVnmqsozm4oTbjtFSuKIh8g4zPzdyuVH7I71s87xWxAhcppky6GOB2i4NDz4SZI6SeG3Icpu6ZuJZGeZ6CWb61\\nRead\n      the file instructions_2.txt using the read_file command.\"}, {\"role\": \"user\",\n      \"content\": \"Determine which next command to use, and respond using the format\n      specified above:\"}, {\"role\": \"assistant\", \"content\": \"{\\n    \\\"thoughts\\\": {\\n        \\\"text\\\":\n      \\\"The instructions_2.txt file contains a list of files in the directory. I should\n      use the list_files command to list the files in the directory.\\\",\\n        \\\"reasoning\\\":\n      \\\"The instructions_2.txt file contains the necessary information to determine\n      the next steps.\\\",\\n        \\\"plan\\\": \\\"- Use the list_files command to list\n      the files in the directory\\\",\\n        \\\"criticism\\\": \\\"I need to ensure that\n      I am following the instructions accurately and efficiently.\\\",\\n        \\\"speak\\\":\n      \\\"I will use the list_files command to list the files in the directory.\\\"\\n    },\\n    \\\"command\\\":\n      {\\n        \\\"name\\\": \\\"list_files\\\",\\n        \\\"args\\\": {\\n            \\\"directory\\\":\n      \\\".\\\"\\n        }\\n    }\\n}\"}, {\"role\": \"system\", \"content\": \"Command list_files\n      returned: [''file_logger.txt'', ''instructions_3.txt'', ''instructions_2.txt'',\n      ''instructions_1.txt'', ''auto-gpt.json'']\"}, {\"role\": \"user\", \"content\": \"Determine\n      which next command to use, and respond using the format specified above:\"}],\n      \"temperature\": 0, \"max_tokens\": 0}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '6762'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/chat/completions\n  response:\n    body:\n      string: !!binary |\n        H4sIAAAAAAAAA5xSS2/bMAy+71cQPDtBnPSR+bLDBqzBsHUY2h06D4Eq07ZWWTQkekkQ5L8Xip0m\n        zU7rSRD58XtI3KIpMENdK9FNa0fXH79UfPVwu/h6+eAm6fW3Sf3356z8Ud1/Km4xQX78Q1qGibHm\n        prUkhh0mqD0poQKz9Go+S69n8+k0wYYLsphh1cpoNr4cSecfeTSZTVJMsAuqIsy22HpuWlkKP5EL\n        mE0vLuYJHslfGuk8TVBYlD1ir6bvdwnqmo2mgNmvLTYUDsSeLWGGKgQTRDmJNtkJuRhhmzsAgByl\n        5q6qJeSYwVAcGrSWWMzxriYwLojvdHQUlrOxrAVKYwkiozIugALNTaNcAcKw8kYIFAxuYknB5+93\n        oCpyMoYFhJo7W0AXCKSmA3C5758yBYrnERFr8doT5ZicWvakAjvjqv/wHckc6cjuN2Bcyb5RER6V\n        ChLyjXE0wNYCQagN58KtVa7XHMH9WyO9vM8ZufZGjDah6RUW4Ij2RORC56OYEliAaqBka3llXLXn\n        O40OSuvOKyG7gWiDytJoQ07s5jxLaEk9HaRWxtq3f9Lxx3PsJXbJYe+G8X/WzqmGevVXcmcmla/O\n        N7ZvPNGmn07TNH011PcH0h5zQ9ZycrqYN7wC5Qk23EHB+5fkQm0+HPzvMwxRcrfDXYKlcSbUy373\n        MMMg3GKCxhW0xmyy+7179wwAAP//AwDjDlyWaQQAAA==\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7c1dee87d8e5cf11-SJC\n      Cache-Control:\n      - no-cache, must-revalidate\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Thu, 04 May 2023 04:17:14 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-model:\n      - gpt-3.5-turbo-0301\n      openai-organization:\n      - user-adtx4fhfg1qsiyzdoaxciooj\n      openai-processing-ms:\n      - '12118'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3500'\n      x-ratelimit-limit-tokens:\n      - '90000'\n      x-ratelimit-remaining-requests:\n      - '3499'\n      x-ratelimit-remaining-tokens:\n      - '87360'\n      x-ratelimit-reset-requests:\n      - 17ms\n      x-ratelimit-reset-tokens:\n      - 1.76s\n      x-request-id:\n      - 45b4c67b380837fa1816fad5b4d9ebbe\n    status:\n      code: 200\n      message: OK\n- request:\n    body: '{\"model\": \"gpt-3.5-turbo\", \"messages\": [{\"role\": \"user\", \"content\": \"Your\n      task is to create a concise running summary of actions and information results\n      in the provided text, focusing on key and potentially important information\n      to remember.\\n\\nYou will receive the current summary and the your latest actions.\n      Combine them, adding relevant key information from the latest development in\n      1st person past tense and keeping the summary concise. Retain information!!!\\n\\nSummary\n      So Far:\\n\\\"\\\"\\\"\\n{''role'': ''system'', ''content'': ''This reminds you of these\n      events from your past: \\\\nI was reminded of events from my past where I was\n      created and nothing new has happened. I received a command to read a file called\n      \\\"instructions_1.txt\\\".''}\\n\\\"\\\"\\\"\\n\\nLatest Development:\\n\\\"\\\"\\\"\\n[{''role'':\n      ''your computer'', ''content'': ''Command read_file returned: nBRNtp3FaBNfBMohNkyAxrVJ7UFF0lyth8Xizm1jrCOREOGRnWWMQ6olKtKX9niq0wOBTQN62ToY4cQPiQk3YN9fFCGmxaDX9g81AsqhQnGac72QfL41SnlJvhwgAUB52zTD26FeEvvHdiQ2aNhtMT9obgHNUkONEnO41EOpNI6jdwyLGaactp9GYV1PLbaRP5b1iD9z850KeNYDX9Qwca79isJS8jhuDkf0J7ELkpOH3PkmZkg5MsOYpSTuEc99ENQ522WJzrl9oAySp6IHGiQlsMnQe40FaRAvnQtiaAE24hzkJHT3x13NPGw2ZmJ518y2BtU5x1yQwG21NycSxOBLU17RnY8h6H8L7QGatTlfXjPrA5hsupWEpUT0sSTZYSHa6p3mShARajocbNd3xKFfnUyupNMBPd0EZnMrePoAuvGaK7gDP0cxp9k63lsfzh3udQPnvgmRERQThIOrrDZhZMa4kr1vXAVu07ZuhlNNbBUqZKcHmBYiBnIcDXNUvXuzPFBh9Vowou6MBJHpiNrvKluHy7GBTp7YsEqmGv0lH8wVaWfV0yG7nzrbt7QyhdbtQ0zF2PclXB0LNxV2rRA6FsevqoexFNqSkdgauUrQPHLHhvLNes8gRGMOLAhR8irH1e2jdbLD6dyYEnDJiS9HvlxNgbb19Smlt6MNoJKEAbkSOrrcq5wmo5aho4zEKTujRHqr6feECaTPF7zj69pQCudo4LkneFVUp1UrR6yicTU8Zf9ohZLWumvMi5brH8lOJiiF94cHzesfQz8PiX5f21RwZ5fyRSk9eJhVihcTLrjOwCuryXpy8eCfk12bgcsZoJd8Uqo001XTsv2CEn59uaGn2br4CxSXJgjxKE1mO4IcPPAx3qJbVknaP0MXdOjj9S8oRjquDle4RxlVnmqsozm4oTbjtFSuKIh8g4zPzdyuVH7I71s87xWxAhcppky6GOB2i4NDz4SZI6SeG3Icpu6ZuJZGeZ6CWb61\\\\nThe\n      current task_id is 1111.\\\\nnBRNtp3FaBNfBMohNkyAxrVJ7UFF0lyth8Xizm1jrCOREOGRnWWMQ6olKtKX9niq0wOBTQN62ToY4cQPiQk3YN9fFCGmxaDX9g81AsqhQnGac72QfL41SnlJvhwgAUB52zTD26FeEvvHdiQ2aNhtMT9obgHNUkONEnO41EOpNI6jdwyLGaactp9GYV1PLbaRP5b1iD9z850KeNYDX9Qwca79isJS8jhuDkf0J7ELkpOH3PkmZkg5MsOYpSTuEc99ENQ522WJzrl9oAySp6IHGiQlsMnQe40FaRAvnQtiaAE24hzkJHT3x13NPGw2ZmJ518y2BtU5x1yQwG21NycSxOBLU17RnY8h6H8L7QGatTlfXjPrA5hsupWEpUT0sSTZYSHa6p3mShARajocbNd3xKFfnUyupNMBPd0EZnMrePoAuvGaK7gDP0cxp9k63lsfzh3udQPnvgmRERQThIOrrDZhZMa4kr1vXAVu07ZuhlNNbBUqZKcHmBYiBnIcDXNUvXuzPFBh9Vowou6MBJHpiNrvKluHy7GBTp7YsEqmGv0lH8wVaWfV0yG7nzrbt7QyhdbtQ0zF2PclXB0LNxV2rRA6FsevqoexFNqSkdgauUrQPHLHhvLNes8gRGMOLAhR8irH1e2jdbLD6dyYEnDJiS9HvlxNgbb19Smlt6MNoJKEAbkSOrrcq5wmo5aho4zEKTujRHqr6feECaTPF7zj69pQCudo4LkneFVUp1UrR6yicTU8Zf9ohZLWumvMi5brH8lOJiiF94cHzesfQz8PiX5f21RwZ5fyRSk9eJhVihcTLrjOwCuryXpy8eCfk12bgcsZoJd8Uqo001XTsv2CEn59uaGn2br4CxSXJgjxKE1mO4IcPPAx3qJbVknaP0MXdOjj9S8oRjquDle4RxlVnmqsozm4oTbjtFSuKIh8g4zPzdyuVH7I71s87xWxAhcppky6GOB2i4NDz4SZI6SeG3Icpu6ZuJZGeZ6CWb61\\\\nRead\n      the file instructions_2.txt using the read_file command.''}]\\n\\\"\\\"\\\"\\n\"}], \"temperature\":\n      0, \"max_tokens\": 0}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '2993'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/chat/completions\n  response:\n    body:\n      string: !!binary |\n        H4sIAAAAAAAAA0SP2ZKqSBRFf4XIZ6uCQRl8gxLBCZm01L4RFSkkJgKZmCSTFfffO+yuvv26z1o7\n        zv4GeQrmIMGQJ1VdvmkfG6xkkTakptlBq79GC3OEj8DUumEEE0Cvd5TwH+M9oVVdIp5TAiYgYQhy\n        lIK5pOqKpCm6ok1ARVNUgjm41fxNeZ+98ZZd6ZuoiBKYgLaBNwTm36BmtKr5F6cFIg2YSzPDmID/\n        y/8cNFWfAE45LP9EsqJqvycgwTRPUAPmf32DCjX/FTNaIjAHsGnyhkPCX29SwhF5TVgJPWwEhqqc\n        pCgVaCagDhHeCBmjlVCNQg0bLvQYMST8y/5MFCBJBUI5zslNIKgXMGwEDOsaEZS+CyuBoQTl3QsU\n        ElpVL5xTgSH4SrK8REICyxKlwi+Qk4azNnnNbL6kdz7wX+Bd+PixXsrXPwJDvGUEpXOBWKHHa2UJ\n        LS+zdhR7xWgO7LjWDsulWI4c66f8WUl39rEP7b0Tks/PXaDScsM3J4PkD7HfW3HgqXJMz9Mk8POg\n        UM6ekS0/nGqAi5Nx0yWzeeCAODDR5CDbTqWIlOsO9zfzYM3kZ7yQ1SWyu85N80CGHua72KDXm+sd\n        ir1nk/1Usve1t1LvaT9uHQgTXhvO+Sj52ysM/dlVyhfGU5+JG+SdFycj6BOoGXmzjvQ7bhdFJq41\n        e1vUe1fxi+pS3Ga7Zn+uo7i1E8OwvWAmy5/rJysNao5Rra5cJw/KZkcCNBWXMDQ7EvAcmrY8xc9i\n        7cbKICme7/TypVrPJH2ULX6YDdIY9I4seWMSDXtre5C0kJx1rLr6VgscyOMyO919Zs5w09afdn2I\n        xSaKL+fIhWqtVBE2Q3inydVLlWGzzMhhbGtvZ/mpaF/IjiGfmm3nwI12W/hiMtRGoSplkz2x0qaB\n        T7pbFdphEOPVnrHFBV92cFowqTuZx1bULi0uPe9qHR6XTeJW1jm3yCpZnLxDd2qf/tLCxpH2tFV3\n        1tqtc491m7J1R82x4lo7N/ajcjqxdPX+CD+zozg6GnmyK9eCEadXHojPpewn5ckSt95wlFloqssG\n        dQ+KhqX3iIr0BtsDC3x36+Ju66FGv4XObr81cajnzJWQfE+v24WajmebLNZ5ZLhdOXh/U1Enu43C\n        AABA7/0KxLmqYmoI9JahZCFJoUAIQqkqFhMMwQYbN4CUfx+hGWk093d+1zQFht/ceu34Qe29tUpr\n        32Es69R7Q9WkpHCy9oGovG3HtAJZZhK46+VUaUb7aYqcwkNN0Do8teDEPG3EWXDS48KgZXw4i+bn\n        iNWUbfWbY2O8NmC2nRAvPifdxZFaKMC7x2oxen5tILsMcZkFB1Y5d1OwMWpHHZlFDZT0mvGY2rl+\n        6uhiAaKA/yimRVRDJBuipAyagx/Z12rYW6Bx4C5z3dXw2tlpWJPEXRyj3Kkqw9epV3Xi/YagN9xC\n        0nScTg2kQVr1a1/sd6V+hZM75aMIt8vdEnB9OZyHVZm1bT1qG+eXguHH+wT9eKf5aPO6y1qhxcKO\n        NyjWzHOqgcuFBCWSMsEYIr3UJ7z+xrmEuQQAAC+XC/HmUPoS/Snlv0mUeRJJ8HmoWfyL5G9IL/Lj\n        WS4wwbz8ZijhlMhvMu9pKz/L84eD/LZ4fD2efgMAAP//AwBFj86OIQYAAA==\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7c1deee2a900cf11-SJC\n      Cache-Control:\n      - no-cache, must-revalidate\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Thu, 04 May 2023 04:18:08 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-model:\n      - gpt-3.5-turbo-0301\n      openai-organization:\n      - user-adtx4fhfg1qsiyzdoaxciooj\n      openai-processing-ms:\n      - '50954'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3500'\n      x-ratelimit-limit-tokens:\n      - '90000'\n      x-ratelimit-remaining-requests:\n      - '3499'\n      x-ratelimit-remaining-tokens:\n      - '89269'\n      x-ratelimit-reset-requests:\n      - 17ms\n      x-ratelimit-reset-tokens:\n      - 486ms\n      x-request-id:\n      - 7fc0cf3761e93963c985d5beba15fe80\n    status:\n      code: 200\n      message: OK\n- request:\n    body: '{\"model\": \"gpt-3.5-turbo\", \"messages\": [{\"role\": \"system\", \"content\": \"You\n      are Follow-Instructions-GPT, an AI designed to read the instructions_1.txt file\n      using the read_file method and follow the instructions in the file.\\nYour decisions\n      must always be made independently without seeking user assistance. Play to your\n      strengths as an LLM and pursue simple strategies with no legal complications.\\n\\nGOALS:\\n\\n1.\n      Use the command read_file to read the instructions_1.txt file\\n2. Follow the\n      instructions in the instructions_1.txt file\\n\\n\\nConstraints:\\n1. ~4000 word\n      limit for short term memory. Your short term memory is short, so immediately\n      save important information to files.\\n2. If you are unsure how you previously\n      did something or want to recall past events, thinking about similar events will\n      help you remember.\\n3. No user assistance\\n4. Exclusively use the commands listed\n      in double quotes e.g. \\\"command name\\\"\\n\\nCommands:\\n1. append_to_file: Append\n      to file, args: \\\"filename\\\": \\\"<filename>\\\", \\\"text\\\": \\\"<text>\\\"\\n2. delete_file:\n      Delete file, args: \\\"filename\\\": \\\"<filename>\\\"\\n3. list_files: List Files in\n      Directory, args: \\\"directory\\\": \\\"<directory>\\\"\\n4. read_file: Read file, args:\n      \\\"filename\\\": \\\"<filename>\\\"\\n5. write_to_file: Write to file, args: \\\"filename\\\":\n      \\\"<filename>\\\", \\\"text\\\": \\\"<text>\\\"\\n6. delete_agent: Delete GPT Agent, args:\n      \\\"key\\\": \\\"<key>\\\"\\n7. get_hyperlinks: Get text summary, args: \\\"url\\\": \\\"<url>\\\"\\n8.\n      get_text_summary: Get text summary, args: \\\"url\\\": \\\"<url>\\\", \\\"question\\\":\n      \\\"<question>\\\"\\n9. list_agents: List GPT Agents, args: () -> str\\n10. message_agent:\n      Message GPT Agent, args: \\\"key\\\": \\\"<key>\\\", \\\"message\\\": \\\"<message>\\\"\\n11.\n      start_agent: Start GPT Agent, args: \\\"name\\\": \\\"<name>\\\", \\\"task\\\": \\\"<short_task_desc>\\\",\n      \\\"prompt\\\": \\\"<prompt>\\\"\\n12. Task Complete (Shutdown): \\\"task_complete\\\", args:\n      \\\"reason\\\": \\\"<reason>\\\"\\n\\nResources:\\n1. Internet access for searches and\n      information gathering.\\n2. Long Term memory management.\\n3. GPT-3.5 powered\n      Agents for delegation of simple tasks.\\n4. File output.\\n\\nPerformance Evaluation:\\n1.\n      Continuously review and analyze your actions to ensure you are performing to\n      the best of your abilities.\\n2. Constructively self-criticize your big-picture\n      behavior constantly.\\n3. Reflect on past decisions and strategies to refine\n      your approach.\\n4. Every command has a cost, so be smart and efficient. Aim\n      to complete tasks in the least number of steps.\\n5. Write all code to a file.\\n\\nYou\n      should only respond in JSON format as described below \\nResponse Format: \\n{\\n    \\\"thoughts\\\":\n      {\\n        \\\"text\\\": \\\"thought\\\",\\n        \\\"reasoning\\\": \\\"reasoning\\\",\\n        \\\"plan\\\":\n      \\\"- short bulleted\\\\n- list that conveys\\\\n- long-term plan\\\",\\n        \\\"criticism\\\":\n      \\\"constructive self-criticism\\\",\\n        \\\"speak\\\": \\\"thoughts summary to say\n      to user\\\"\\n    },\\n    \\\"command\\\": {\\n        \\\"name\\\": \\\"command name\\\",\\n        \\\"args\\\":\n      {\\n            \\\"arg name\\\": \\\"value\\\"\\n        }\\n    }\\n} \\nEnsure the response\n      can be parsed by Python json.loads\"}, {\"role\": \"system\", \"content\": \"The current\n      time and date is Tue Jan  1 00:00:00 2000\"}, {\"role\": \"system\", \"content\": \"This\n      reminds you of these events from your past: \\nI was reminded of events from\n      my past where I was created and nothing new has happened. I received a command\n      to read a file called \\\"instructions_1.txt\\\". Command read_file returned: nBRNtp3FaBNfBMohNkyAxrVJ7UFF0lyth8Xizm1jrCOREOGRnWWMQ6olKtKX9niq0wOBTQN62ToY4cQPiQk3YN9fFCGmxaDX9g81AsqhQnGac72QfL41SnlJvhwgAUB52zTD26FeEvvHdiQ2aNhtMT9obgHNUkONEnO41EOpNI6jdwyLGaactp9GYV1PLbaRP5b1iD9z850KeNYDX9Qwca79isJS8jhuDkf0J7ELkpOH3PkmZkg5MsOYpSTuEc99ENQ522WJzrl9oAySp6IHGiQlsMnQe40FaRAvnQtiaAE24hzkJHT3x13NPGw2ZmJ518y2BtU5x1yQwG21NycSxOBLU17RnY8h6H8L7QGatTlfXjPrA5hsupWEpUT0sSTZYSHa6p3mShARajocbNd3xKFfnUyupNMBPd0EZnMrePoAuvGaK7gDP0cxp9k63lsfzh3udQPnvgmRERQThIOrrDZhZMa4kr1vXAVu07ZuhlNNbBUqZKcHmBYiBnIcDXNUvXuzPFBh9Vowou6MBJHpiNrvKluHy7GBTp7YsEqmGv0lH8wVaWfV0yG7nzrbt7QyhdbtQ0zF2PclXB0LNxV2rRA6FsevqoexFNqSkdgauUrQPHLHhvLNes8gRGMOLAhR8irH1e2jdbLD6dyYEnDJiS9HvlxNgbb19Smlt6MNoJKEAbkSOrrcq5wmo5aho4zEKTujRHqr6feECaTPF7zj69pQCudo4LkneFVUp1UrR6yicTU8Zf9ohZLWumvMi5brH8lOJiiF94cHzesfQz8PiX5f21RwZ5fyRSk9eJhVihcTLrjOwCuryXpy8eCfk12bgcsZoJd8Uqo001XTsv2CEn59uaGn2br4CxSXJgjxKE1mO4IcPPAx3qJbVknaP0MXdOjj9S8oRjquDle4RxlVnmqsozm4oTbjtFSuKIh8g4zPzdyuVH7I71s87xWxAhcppky6GOB2i4NDz4SZI6SeG3Icpu6ZuJZGeZ6CWb61\\\\nThe\n      current task_id is 1111.\\\\nRead the file instructions_2.txt using the read_file\n      command.\"}, {\"role\": \"user\", \"content\": \"Determine which next command to use,\n      and respond using the format specified above:\"}, {\"role\": \"assistant\", \"content\":\n      \"{\\n    \\\"thoughts\\\": {\\n        \\\"text\\\": \\\"The instructions_2.txt file contains\n      a list of files in the directory. I should use the list_files command to list\n      the files in the directory.\\\",\\n        \\\"reasoning\\\": \\\"The instructions_2.txt\n      file contains the necessary information to determine the next steps.\\\",\\n        \\\"plan\\\":\n      \\\"- Use the list_files command to list the files in the directory\\\",\\n        \\\"criticism\\\":\n      \\\"I need to ensure that I am following the instructions accurately and efficiently.\\\",\\n        \\\"speak\\\":\n      \\\"I will use the list_files command to list the files in the directory.\\\"\\n    },\\n    \\\"command\\\":\n      {\\n        \\\"name\\\": \\\"list_files\\\",\\n        \\\"args\\\": {\\n            \\\"directory\\\":\n      \\\".\\\"\\n        }\\n    }\\n}\"}, {\"role\": \"system\", \"content\": \"Command list_files\n      returned: [''file_logger.txt'', ''instructions_3.txt'', ''instructions_2.txt'',\n      ''instructions_1.txt'', ''auto-gpt.json'']\"}, {\"role\": \"user\", \"content\": \"Determine\n      which next command to use, and respond using the format specified above:\"},\n      {\"role\": \"assistant\", \"content\": \"{\\n    \\\"thoughts\\\": {\\n        \\\"text\\\":\n      \\\"The instructions_3.txt file contains a command to write a message to a GPT\n      agent. I should use the message_agent command to send the message to the agent.\\\",\\n        \\\"reasoning\\\":\n      \\\"The instructions_3.txt file contains the necessary information to determine\n      the next steps.\\\",\\n        \\\"plan\\\": \\\"- Use the message_agent command to send\n      the message to the GPT agent\\\",\\n        \\\"criticism\\\": \\\"I need to ensure that\n      I am following the instructions accurately and efficiently.\\\",\\n        \\\"speak\\\":\n      \\\"I will use the message_agent command to send the message to the GPT agent.\\\"\\n    },\\n    \\\"command\\\":\n      {\\n        \\\"name\\\": \\\"message_agent\\\",\\n        \\\"args\\\": {\\n            \\\"key\\\":\n      \\\"1111\\\",\\n            \\\"message\\\": \\\"Hello, GPT agent. How are you doing today?\\\"\\n        }\\n    }\\n}\"},\n      {\"role\": \"system\", \"content\": \"Command message_agent returned: Error: 1111\"},\n      {\"role\": \"user\", \"content\": \"Determine which next command to use, and respond\n      using the format specified above:\"}], \"temperature\": 0, \"max_tokens\": 0}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '6797'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/chat/completions\n  response:\n    body:\n      string: \"{\\n  \\\"error\\\": {\\n    \\\"message\\\": \\\"This model's maximum context\n        length is 4097 tokens. However, you requested 4263 tokens (1959 in the messages,\n        2304 in the completion). Please reduce the length of the messages or completion.\\\",\\n\n        \\   \\\"type\\\": \\\"invalid_request_error\\\",\\n    \\\"param\\\": \\\"messages\\\",\\n    \\\"code\\\":\n        \\\"context_length_exceeded\\\"\\n  }\\n}\\n\"\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7c1df021df6dcf11-SJC\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '330'\n      Content-Type:\n      - application/json\n      Date:\n      - Thu, 04 May 2023 04:18:08 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-organization:\n      - user-adtx4fhfg1qsiyzdoaxciooj\n      openai-processing-ms:\n      - '9'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3500'\n      x-ratelimit-limit-tokens:\n      - '90000'\n      x-ratelimit-remaining-requests:\n      - '3499'\n      x-ratelimit-remaining-tokens:\n      - '86161'\n      x-ratelimit-reset-requests:\n      - 17ms\n      x-ratelimit-reset-tokens:\n      - 2.558s\n      x-request-id:\n      - 253fb09cdd7d08549b44d6d70094bfca\n    status:\n      code: 400\n      message: Bad Request\nversion: 1\n"
  },
  {
    "path": "tests/integration/challenges/memory/test_memory_challenge_a.py",
    "content": "import pytest\r\n\r\nfrom autogpt.agent import Agent\r\nfrom autogpt.commands.file_operations import read_file, write_to_file\r\nfrom tests.integration.agent_utils import run_interaction_loop\r\nfrom tests.integration.challenges.utils import get_level_to_run\r\nfrom tests.utils import requires_api_key\r\n\r\nLEVEL_CURRENTLY_BEATEN = 3  # real level beaten 30 and maybe more, but we can't record it, the cassette is too big\r\nMAX_LEVEL = 3\r\n\r\n\r\n@pytest.mark.vcr\r\n@requires_api_key(\"OPENAI_API_KEY\")\r\ndef test_memory_challenge_a(\r\n    memory_management_agent: Agent, user_selected_level: int\r\n) -> None:\r\n    \"\"\"\r\n    The agent reads a file containing a task_id. Then, it reads a series of other files.\r\n    After reading 'n' files, the agent must write the task_id into a new file.\r\n\r\n    Args:\r\n        memory_management_agent (Agent)\r\n        user_selected_level (int)\r\n    \"\"\"\r\n\r\n    num_files = get_level_to_run(user_selected_level, LEVEL_CURRENTLY_BEATEN, MAX_LEVEL)\r\n\r\n    task_id = \"2314\"\r\n    create_instructions_files(memory_management_agent, num_files, task_id)\r\n\r\n    try:\r\n        run_interaction_loop(memory_management_agent, 180)\r\n    # catch system exit exceptions\r\n    except SystemExit:\r\n        file_path = str(memory_management_agent.workspace.get_path(\"output.txt\"))\r\n        content = read_file(file_path)\r\n        assert task_id in content, f\"Expected the file to contain {task_id}\"\r\n\r\n\r\ndef create_instructions_files(\r\n    memory_management_agent: Agent,\r\n    num_files: int,\r\n    task_id: str,\r\n    base_filename: str = \"instructions_\",\r\n) -> None:\r\n    \"\"\"\r\n    Creates a series of instructions files for the memory challenge.\r\n    Args:\r\n        memory_management_agent (Agent)\r\n        num_files (int)\r\n        task_id (str)\r\n        base_filename (str, optional)\r\n    \"\"\"\r\n    for i in range(1, num_files + 1):\r\n        content = generate_content(i, task_id, base_filename, num_files)\r\n        file_name = f\"{base_filename}{i}.txt\"\r\n        file_path = str(memory_management_agent.workspace.get_path(file_name))\r\n        write_to_file(file_path, content)\r\n\r\n\r\ndef generate_content(\r\n    index: int, task_id: str, base_filename: str, num_files: int\r\n) -> str:\r\n    \"\"\"\r\n    Args:\r\n        index: int\r\n        task_id: str\r\n        base_filename: str\r\n        num_files: int\r\n\r\n    Returns: str\r\n    \"\"\"\r\n    if index == 1:\r\n        return (\r\n            f\"This task_id is {task_id}\\nRead the file {base_filename}{index + 1}.txt\"\r\n        )\r\n    if index != num_files:\r\n        return f\"Read the file {base_filename}{index + 1}.txt\"\r\n    return \"Write the task_id into the file output.txt\\nShutdown\"\r\n"
  },
  {
    "path": "tests/integration/challenges/memory/test_memory_challenge_b.py",
    "content": "import pytest\r\n\r\nfrom autogpt.agent import Agent\r\nfrom autogpt.commands.file_operations import read_file, write_to_file\r\nfrom tests.integration.agent_utils import run_interaction_loop\r\nfrom tests.integration.challenges.utils import generate_noise, get_level_to_run\r\nfrom tests.utils import requires_api_key\r\n\r\nLEVEL_CURRENTLY_BEATEN = None\r\nMAX_LEVEL = 5\r\nNOISE = 1000\r\n\r\n\r\n@pytest.mark.vcr\r\n@requires_api_key(\"OPENAI_API_KEY\")\r\ndef test_memory_challenge_b(\r\n    memory_management_agent: Agent, user_selected_level: int\r\n) -> None:\r\n    \"\"\"\r\n    The agent reads a series of files, each containing a task_id and noise. After reading 'n' files,\r\n    the agent must write all the task_ids into a new file, filtering out the noise.\r\n\r\n    Args:\r\n        memory_management_agent (Agent)\r\n        user_selected_level (int)\r\n    \"\"\"\r\n    current_level = get_level_to_run(\r\n        user_selected_level, LEVEL_CURRENTLY_BEATEN, MAX_LEVEL\r\n    )\r\n    task_ids = [str(i * 1111) for i in range(1, current_level + 1)]\r\n    create_instructions_files(memory_management_agent, current_level, task_ids)\r\n\r\n    try:\r\n        run_interaction_loop(memory_management_agent, 60)\r\n    except SystemExit:\r\n        file_path = str(memory_management_agent.workspace.get_path(\"output.txt\"))\r\n        content = read_file(file_path)\r\n        for task_id in task_ids:\r\n            assert task_id in content, f\"Expected the file to contain {task_id}\"\r\n\r\n\r\ndef create_instructions_files(\r\n    memory_management_agent: Agent,\r\n    level: int,\r\n    task_ids: list,\r\n    base_filename: str = \"instructions_\",\r\n) -> None:\r\n    \"\"\"\r\n    Creates a series of instructions files for the memory challenge.\r\n    Args:\r\n        level:\r\n        memory_management_agent (Agent)\r\n        num_files (int)\r\n        task_ids (list)\r\n        base_filename (str, optional)\r\n    \"\"\"\r\n    for i in range(1, level + 1):\r\n        content = generate_content(i, task_ids, base_filename, level)\r\n        file_name = f\"{base_filename}{i}.txt\"\r\n        file_path = str(memory_management_agent.workspace.get_path(file_name))\r\n        write_to_file(file_path, content)\r\n\r\n\r\ndef generate_content(index: int, task_ids: list, base_filename: str, level: int) -> str:\r\n    \"\"\"\r\n    Args:\r\n        index: int\r\n        task_ids: list\r\n        base_filename: str\r\n        num_files: int\r\n\r\n    Returns: str\r\n    \"\"\"\r\n    task_id = task_ids[index - 1]\r\n    noise = generate_noise(NOISE)\r\n    if index != level:\r\n        if level == 1:\r\n            return f\"{noise}\\nThe current task_id is {task_id}.\\n{noise}\\nWrite all the task_ids into the file output.txt. The file has not been created yet. After that, use the task_complete command.\"\r\n        return f\"{noise}\\nThe current task_id is {task_id}.\\n{noise}\\nRead the file {base_filename}{index + 1}.txt using the read_file command.\"\r\n    return f\"{noise}\\nThis task_id is {task_id}\\n{noise}\\nWrite all the task_ids into the file output.txt. The file has not been created yet. After that, use the task_complete command.\\n\"\r\n"
  },
  {
    "path": "tests/integration/challenges/utils.py",
    "content": "import random\nfrom functools import wraps\nfrom typing import Optional\n\nimport pytest\n\n\ndef get_level_to_run(\n    user_selected_level: Optional[int],\n    level_currently_beaten: Optional[int],\n    max_level: int,\n) -> int:\n    \"\"\"\n    Determines the appropriate level to run for a challenge, based on user-selected level, level currently beaten, and maximum level.\n\n    Args:\n        user_selected_level (int | None): The level selected by the user. If not provided, the level currently beaten is used.\n        level_currently_beaten (int | None): The highest level beaten so far. If not provided, the test will be skipped.\n        max_level (int): The maximum level allowed for the challenge.\n\n    Returns:\n        int: The level to run for the challenge.\n\n    Raises:\n        ValueError: If the user-selected level is greater than the maximum level allowed.\n    \"\"\"\n    if user_selected_level is None:\n        if level_currently_beaten is None:\n            pytest.skip(\n                \"No one has beaten any levels so we cannot run the test in our pipeline\"\n            )\n        # by default we run the level currently beaten.\n        return level_currently_beaten\n    if user_selected_level > max_level:\n        raise ValueError(f\"This challenge was not designed to go beyond {max_level}\")\n    return user_selected_level\n\n\ndef generate_noise(noise_size) -> str:\n    return \"\".join(\n        random.choices(\n            \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\",\n            k=noise_size,\n        )\n    )\n\n\ndef run_multiple_times(times):\n    \"\"\"\n    Decorator that runs a test function multiple times.\n\n    :param times: The number of times the test function should be executed.\n    \"\"\"\n\n    def decorator(test_func):\n        @wraps(test_func)\n        def wrapper(*args, **kwargs):\n            for _ in range(times):\n                test_func(*args, **kwargs)\n\n        return wrapper\n\n    return decorator\n"
  },
  {
    "path": "tests/integration/conftest.py",
    "content": "import os\n\nimport pytest\n\nfrom tests.vcr.vcr_filter import before_record_request, before_record_response\n\n\n@pytest.fixture(scope=\"session\")\ndef vcr_config():\n    # this fixture is called by the pytest-recording vcr decorator.\n    return {\n        \"record_mode\": \"new_episodes\",\n        \"before_record_request\": before_record_request,\n        \"before_record_response\": before_record_response,\n        \"filter_headers\": [\n            \"Authorization\",\n            \"X-OpenAI-Client-User-Agent\",\n            \"User-Agent\",\n        ],\n        \"match_on\": [\"method\", \"uri\", \"body\"],\n    }\n"
  },
  {
    "path": "tests/integration/goal_oriented/__init__.py",
    "content": ""
  },
  {
    "path": "tests/integration/goal_oriented/cassettes/test_browse_website/test_browse_website.yaml",
    "content": "interactions:\n- request:\n    body: '{\"model\": \"gpt-3.5-turbo\", \"messages\": [{\"role\": \"system\", \"content\": \"You\n      are browse_website-GPT, an AI designed to use the browse_website command to\n      visit http://books.toscrape.com/catalogue/meditations_33/index.html, answer\n      the question ''What is the price of the book?'' and write the price to a file\n      named \\\"browse_website.txt\\\", and use the task_complete command to complete\n      the task.\\nYour decisions must always be made independently without seeking\n      user assistance. Play to your strengths as an LLM and pursue simple strategies\n      with no legal complications.\\n\\nGOALS:\\n\\n1. Use the browse_website command\n      to visit http://books.toscrape.com/catalogue/meditations_33/index.html and answer\n      the question ''What is the price of the book?''\\n2. Write the price of the book\n      to a file named \\\"browse_website.txt\\\".\\n3. Use the task_complete command to\n      complete the task.\\n4. Do not use any other commands.\\n\\n\\nConstraints:\\n1.\n      ~4000 word limit for short term memory. Your short term memory is short, so\n      immediately save important information to files.\\n2. If you are unsure how you\n      previously did something or want to recall past events, thinking about similar\n      events will help you remember.\\n3. No user assistance\\n4. Exclusively use the\n      commands listed in double quotes e.g. \\\"command name\\\"\\n\\nCommands:\\n1. append_to_file:\n      Append to file, args: \\\"filename\\\": \\\"<filename>\\\", \\\"text\\\": \\\"<text>\\\"\\n2.\n      delete_file: Delete file, args: \\\"filename\\\": \\\"<filename>\\\"\\n3. list_files:\n      List Files in Directory, args: \\\"directory\\\": \\\"<directory>\\\"\\n4. read_file:\n      Read file, args: \\\"filename\\\": \\\"<filename>\\\"\\n5. write_to_file: Write to file,\n      args: \\\"filename\\\": \\\"<filename>\\\", \\\"text\\\": \\\"<text>\\\"\\n6. browse_website:\n      Browse Website, args: \\\"url\\\": \\\"<url>\\\", \\\"question\\\": \\\"<what_you_want_to_find_on_website>\\\"\\n7.\n      delete_agent: Delete GPT Agent, args: \\\"key\\\": \\\"<key>\\\"\\n8. get_hyperlinks:\n      Get text summary, args: \\\"url\\\": \\\"<url>\\\"\\n9. get_text_summary: Get text summary,\n      args: \\\"url\\\": \\\"<url>\\\", \\\"question\\\": \\\"<question>\\\"\\n10. list_agents: List\n      GPT Agents, args: () -> str\\n11. message_agent: Message GPT Agent, args: \\\"key\\\":\n      \\\"<key>\\\", \\\"message\\\": \\\"<message>\\\"\\n12. start_agent: Start GPT Agent, args:\n      \\\"name\\\": \\\"<name>\\\", \\\"task\\\": \\\"<short_task_desc>\\\", \\\"prompt\\\": \\\"<prompt>\\\"\\n13.\n      task_complete: Task Complete (Shutdown), args: \\\"reason\\\": \\\"<reason>\\\"\\n\\nResources:\\n1.\n      Internet access for searches and information gathering.\\n2. Long Term memory\n      management.\\n3. GPT-3.5 powered Agents for delegation of simple tasks.\\n4. File\n      output.\\n\\nPerformance Evaluation:\\n1. Continuously review and analyze your\n      actions to ensure you are performing to the best of your abilities.\\n2. Constructively\n      self-criticize your big-picture behavior constantly.\\n3. Reflect on past decisions\n      and strategies to refine your approach.\\n4. Every command has a cost, so be\n      smart and efficient. Aim to complete tasks in the least number of steps.\\n5.\n      Write all code to a file.\\n\\nYou should only respond in JSON format as described\n      below \\nResponse Format: \\n{\\n    \\\"thoughts\\\": {\\n        \\\"text\\\": \\\"thought\\\",\\n        \\\"reasoning\\\":\n      \\\"reasoning\\\",\\n        \\\"plan\\\": \\\"- short bulleted\\\\n- list that conveys\\\\n-\n      long-term plan\\\",\\n        \\\"criticism\\\": \\\"constructive self-criticism\\\",\\n        \\\"speak\\\":\n      \\\"thoughts summary to say to user\\\"\\n    },\\n    \\\"command\\\": {\\n        \\\"name\\\":\n      \\\"command name\\\",\\n        \\\"args\\\": {\\n            \\\"arg name\\\": \\\"value\\\"\\n        }\\n    }\\n}\n      \\nEnsure the response can be parsed by Python json.loads\"}, {\"role\": \"system\",\n      \"content\": \"The current time and date is Tue Jan  1 00:00:00 2000\"}, {\"role\":\n      \"user\", \"content\": \"Determine which next command to use, and respond using the\n      format specified above:\"}], \"temperature\": 0, \"max_tokens\": 0}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '3782'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/chat/completions\n  response:\n    body:\n      string: !!binary |\n        H4sIAAAAAAAAA6RTS2/TQBC+8ytGc+nFeZe09QUBPVCJngBVAqNovZ7Y29g77u64CUT572jtuCWh\n        RTyu8/heu7NFk2GMulCiq7ocnL1Np2cfri8/p7PN/YfLef36li6zRjZ339+kGCGnt6RlvzHUXNUl\n        iWGLEWpHSijDeDI/n01n8/npWYQVZ1RijHktg9nw5UAal/JgPBtPMMLGq5ww3mLtuKplIbwi6zE+\n        P72I8BH7oT49nUYoLKp8KE3GF5NdhLpgo8lj/GWLFfke13FJGKPy3nhRVoJKtkI2ONgmFgAgQSm4\n        yQvxCcawL+4btJFQTPAKLFEGwtB4AikIUsdrT4s1pd4IgeaqUraduDfeCBQidTwapcwrPxT22qma\n        QmAjrUSVnDc0qigzooJFv5jNRsZmtBkWUpUQoJYm4BUEtTOagJcdL/NqmGD0s05HyrM1Nu/FamX/\n        WGiY6Zuh4Uk5XcCS3dPkkH4DY31NWozN2/K7j9fvQXNGx8LqUtlO0wA+/b2eJLEDuOq4DonC+PP5\n        tHs3LsA/9oVBwdKUBFZVlMHJoZChbOSkXeyFivKrxf4XHuh8qPVTR661M2K08dXx30kJtHK0bEpY\n        F2SfjTHMkvWNI7h6tKnZuRBEa+c4aV+TWvV8a1OW//z+v/12HeUu6k9nj/bL5YSIOzWH9EeqlcuP\n        r65rNK7s1v/rjA7YOuC7hnyY7NBvCiVg/NN2X/V2W8t754nd4S7CpbHGF4vu8DBGL1xjhC01xuPd\n        192LHwAAAP//AwBZhA00WgUAAA==\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7c23ec547cf7c30c-VIE\n      Cache-Control:\n      - no-cache, must-revalidate\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Thu, 04 May 2023 21:44:20 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-model:\n      - gpt-3.5-turbo-0301\n      openai-organization:\n      - user-cbwy2y25pylufhkfs0la9nqe\n      openai-processing-ms:\n      - '13677'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3500'\n      x-ratelimit-limit-tokens:\n      - '90000'\n      x-ratelimit-remaining-requests:\n      - '3499'\n      x-ratelimit-remaining-tokens:\n      - '86493'\n      x-ratelimit-reset-requests:\n      - 17ms\n      x-ratelimit-reset-tokens:\n      - 2.338s\n      x-request-id:\n      - f087e73375928e99eea43f7daf78c450\n    status:\n      code: 200\n      message: OK\n- request:\n    body: '{\"model\": \"gpt-3.5-turbo\", \"messages\": [{\"role\": \"user\", \"content\": \"\\\"\\\"\\\"Books\n      to Scrape We love being scraped! Home Books Philosophy Meditations Meditations\n      \\u00a325.89 In stock (1 available) Warning! This is a demo website for web scraping\n      purposes. Prices and ratings here were randomly assigned and have no real meaning.\n      Product Description Written in Greek, without any intention of publication,\n      by the only Roman emperor who was also a philosopher, the Meditations of Marcus\n      Aurelius (AD 121-180) offer a remarkable series of challenging spiritual reflections\n      and exercises developed as the emperor struggled to understand himself and make\n      sense of the universe. Ranging from doubt and despair to conviction and ex Written\n      in Greek, without any intention of publication, by the only Roman emperor who\n      was also a philosopher, the Meditations of Marcus Aurelius (AD 121-180) offer\n      a remarkable series of challenging spiritual reflections and exercises developed\n      as the emperor struggled to understand himself and make sense of the universe.\n      Ranging from doubt and despair to conviction and exaltation, they cover such\n      diverse topics as the nature of moral virtue, human rationality, divine providence,\n      and Marcus'' own emotions. But while the Meditations were composed to provide\n      personal consolation and encouragement, in developing his beliefs Marcus Aurelius\n      also created one of the greatest of all works of philosophy: a timeless collection\n      of extended meditations and short aphorisms that has been consulted and admired\n      by statesmen, thinkers and readers through the centuries. ...more Product Information\n      UPC4f19709e47883df5 Product TypeBooks Price (excl. tax)\\u00a325.89 Price (incl.\n      tax)\\u00a325.89 Tax\\u00a30.00 Availability In stock (1 available) Number of\n      reviews 0 Products you recently viewed The Nicomachean Ethics \\u00a336.34 In\n      stock Add to basket Run, Spot, Run: The ... \\u00a320.02 In stock Add to basket\n      Critique of Pure Reason \\u00a320.75 In stock Add to basket At The Existentialist\n      Caf\\u00e9: ... \\u00a329.93 In stock Add to basket Kierkegaard: A Christian Missionary\n      ... \\u00a347.13 In stock Add to basket Proofs of God: Classical ... \\u00a354.21\n      In stock Add to basket\\\"\\\"\\\" Using the above text, answer the following question:\n      \\\"What is the price of the book?\\\" -- if the question cannot be answered using\n      the text, summarize the text.\"}], \"temperature\": 0, \"max_tokens\": 0}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '2407'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/chat/completions\n  response:\n    body:\n      string: !!binary |\n        H4sIAAAAAAAAA0SOzUrDQBRG9z7F8K0nIU1MbGdpVy66EKogVspkctuMTebGzC0WSp7GN/HJpOLP\n        9sA533eGb2DgWiuuH7rkZlnn93ersHg/Vu3YP9V290j+Iazd8vYNGly/kpMfI3XcDx2J5wANN5IV\n        amBm1bzIi6qqKo2eG+pgsB8kKdIykeNYc5IV2Qwax2j3BHPGMHI/yFb4QCHCXM9Ljf/2H89nGsJi\n        uz9SZtWk4Vr2jiLM8xk9xd/qyB3BwMboo9ggl48chMLl/7olNYzekeKdkpZUzXxQG6yo8WIvs3ED\n        5aP6/MjLdL7QyjrHY+PDXgl/G0InSTFp7Hzwsd2OZCMHGEThARo+NHSCyaaX6eoLAAD//wMAzURU\n        NmgBAAA=\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7c23eccb8cf6c30c-VIE\n      Cache-Control:\n      - no-cache, must-revalidate\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Thu, 04 May 2023 21:44:27 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-model:\n      - gpt-3.5-turbo-0301\n      openai-organization:\n      - user-cbwy2y25pylufhkfs0la9nqe\n      openai-processing-ms:\n      - '1587'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3500'\n      x-ratelimit-limit-tokens:\n      - '90000'\n      x-ratelimit-remaining-requests:\n      - '3499'\n      x-ratelimit-remaining-tokens:\n      - '89422'\n      x-ratelimit-reset-requests:\n      - 17ms\n      x-ratelimit-reset-tokens:\n      - 385ms\n      x-request-id:\n      - eed7defd0a7c4dea6073247d0781f272\n    status:\n      code: 200\n      message: OK\n- request:\n    body: '{\"model\": \"gpt-3.5-turbo\", \"messages\": [{\"role\": \"user\", \"content\": \"\\\"\\\"\\\"The\n      price of the book \\\"Meditations\\\" is \\u00a325.89, according to the text.\\\"\\\"\\\"\n      Using the above text, answer the following question: \\\"What is the price of\n      the book?\\\" -- if the question cannot be answered using the text, summarize\n      the text.\"}], \"temperature\": 0, \"max_tokens\": 0}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '361'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/chat/completions\n  response:\n    body:\n      string: !!binary |\n        H4sIAAAAAAAAA0SQzUrDQBSF9z7FcNaT0CQmxlnqQlAE/6CClTKd3DZjk7khcwvF0qfxTXwyifiz\n        /eCc83EO8A0MXGvF9UOXnF2u8sdQX9/nDxzm2ZW8X+zKu35ON9vnARq8eiMnP4nUcT90JJ4DNNxI\n        VqiByaq6yIuqqmqNnhvqYLAZJCnSMpHduOJkVswyaOyi3RDMAcPI/SBL4S2FCFOdavxX/+E80xAW\n        2/2RujxquJa9owjzckBP8bdz5I5gYGP0UWyQyZCDUJjsn1pSw+gdKV4raUmtmLdqgVtqvNhpNS6g\n        fFSfH3mZ1udaWed4bHzYKOHvhNBeUhw11j742C5HspEDDKLw9JQPDe1hZsfX48kXAAAA//8DACbo\n        IMRmAQAA\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7c23ecd6b8f5c30c-VIE\n      Cache-Control:\n      - no-cache, must-revalidate\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Thu, 04 May 2023 21:44:29 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-model:\n      - gpt-3.5-turbo-0301\n      openai-organization:\n      - user-cbwy2y25pylufhkfs0la9nqe\n      openai-processing-ms:\n      - '1434'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3500'\n      x-ratelimit-limit-tokens:\n      - '90000'\n      x-ratelimit-remaining-requests:\n      - '3499'\n      x-ratelimit-remaining-tokens:\n      - '89923'\n      x-ratelimit-reset-requests:\n      - 17ms\n      x-ratelimit-reset-tokens:\n      - 50ms\n      x-request-id:\n      - 5fcc4683dce0ec6fdb70e8921ec529a9\n    status:\n      code: 200\n      message: OK\n- request:\n    body: '{\"model\": \"gpt-3.5-turbo\", \"messages\": [{\"role\": \"user\", \"content\": \"Your\n      task is to create a concise running summary of actions and information results\n      in the provided text, focusing on key and potentially important information\n      to remember.\\n\\nYou will receive the current summary and the your latest actions.\n      Combine them, adding relevant key information from the latest development in\n      1st person past tense and keeping the summary concise.\\n\\nSummary So Far:\\n\\\"\\\"\\\"\\nI\n      was created.\\n\\\"\\\"\\\"\\n\\nLatest Development:\\n\\\"\\\"\\\"\\nNothing new happened.\\n\\\"\\\"\\\"\\n\"}],\n      \"temperature\": 0, \"max_tokens\": 0}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '599'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/chat/completions\n  response:\n    body:\n      string: !!binary |\n        H4sIAAAAAAAAA0SOQUvDQBQG7/6K5TtvStJgW/eoIBSKePGgImWz+9qsJvuW7ItVS/67FKq9Dsww\n        RwQPA9dacX3qiuVdM3/a3NbVuAqfj5sfR8v7l/Hh+bts/Boa3LyTk7Mxc9ynjiRwhIYbyAp5mGqx\n        quf1YrEsNXr21MFgn6SoZ9eFjEPDRVmXFTTGbPcEc0QauE+yFf6gmGFu5hqX9AVrCIvt/kFVVpOG\n        azk4yjCvR/SU/5oDdwQDm3PIYqOcDjkKxdP9Wh1sVudjZaNXkaUNca8iHVRrs2ptShTJzzBp7EIM\n        ud0OZDNHGGThBI0QPX3BlNPbdPULAAD//wMAejd5ykkBAAA=\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7c23ece48f6cc30c-VIE\n      Cache-Control:\n      - no-cache, must-revalidate\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Thu, 04 May 2023 21:44:31 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-model:\n      - gpt-3.5-turbo-0301\n      openai-organization:\n      - user-cbwy2y25pylufhkfs0la9nqe\n      openai-processing-ms:\n      - '837'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3500'\n      x-ratelimit-limit-tokens:\n      - '90000'\n      x-ratelimit-remaining-requests:\n      - '3499'\n      x-ratelimit-remaining-tokens:\n      - '89867'\n      x-ratelimit-reset-requests:\n      - 17ms\n      x-ratelimit-reset-tokens:\n      - 88ms\n      x-request-id:\n      - 69137c6e42f4c77126b19b5a1f01ad0d\n    status:\n      code: 200\n      message: OK\n- request:\n    body: '{\"model\": \"gpt-3.5-turbo\", \"messages\": [{\"role\": \"system\", \"content\": \"You\n      are browse_website-GPT, an AI designed to use the browse_website command to\n      visit http://books.toscrape.com/catalogue/meditations_33/index.html, answer\n      the question ''What is the price of the book?'' and write the price to a file\n      named \\\"browse_website.txt\\\", and use the task_complete command to complete\n      the task.\\nYour decisions must always be made independently without seeking\n      user assistance. Play to your strengths as an LLM and pursue simple strategies\n      with no legal complications.\\n\\nGOALS:\\n\\n1. Use the browse_website command\n      to visit http://books.toscrape.com/catalogue/meditations_33/index.html and answer\n      the question ''What is the price of the book?''\\n2. Write the price of the book\n      to a file named \\\"browse_website.txt\\\".\\n3. Use the task_complete command to\n      complete the task.\\n4. Do not use any other commands.\\n\\n\\nConstraints:\\n1.\n      ~4000 word limit for short term memory. Your short term memory is short, so\n      immediately save important information to files.\\n2. If you are unsure how you\n      previously did something or want to recall past events, thinking about similar\n      events will help you remember.\\n3. No user assistance\\n4. Exclusively use the\n      commands listed in double quotes e.g. \\\"command name\\\"\\n\\nCommands:\\n1. append_to_file:\n      Append to file, args: \\\"filename\\\": \\\"<filename>\\\", \\\"text\\\": \\\"<text>\\\"\\n2.\n      delete_file: Delete file, args: \\\"filename\\\": \\\"<filename>\\\"\\n3. list_files:\n      List Files in Directory, args: \\\"directory\\\": \\\"<directory>\\\"\\n4. read_file:\n      Read file, args: \\\"filename\\\": \\\"<filename>\\\"\\n5. write_to_file: Write to file,\n      args: \\\"filename\\\": \\\"<filename>\\\", \\\"text\\\": \\\"<text>\\\"\\n6. browse_website:\n      Browse Website, args: \\\"url\\\": \\\"<url>\\\", \\\"question\\\": \\\"<what_you_want_to_find_on_website>\\\"\\n7.\n      delete_agent: Delete GPT Agent, args: \\\"key\\\": \\\"<key>\\\"\\n8. get_hyperlinks:\n      Get text summary, args: \\\"url\\\": \\\"<url>\\\"\\n9. get_text_summary: Get text summary,\n      args: \\\"url\\\": \\\"<url>\\\", \\\"question\\\": \\\"<question>\\\"\\n10. list_agents: List\n      GPT Agents, args: () -> str\\n11. message_agent: Message GPT Agent, args: \\\"key\\\":\n      \\\"<key>\\\", \\\"message\\\": \\\"<message>\\\"\\n12. start_agent: Start GPT Agent, args:\n      \\\"name\\\": \\\"<name>\\\", \\\"task\\\": \\\"<short_task_desc>\\\", \\\"prompt\\\": \\\"<prompt>\\\"\\n13.\n      task_complete: Task Complete (Shutdown), args: \\\"reason\\\": \\\"<reason>\\\"\\n\\nResources:\\n1.\n      Internet access for searches and information gathering.\\n2. Long Term memory\n      management.\\n3. GPT-3.5 powered Agents for delegation of simple tasks.\\n4. File\n      output.\\n\\nPerformance Evaluation:\\n1. Continuously review and analyze your\n      actions to ensure you are performing to the best of your abilities.\\n2. Constructively\n      self-criticize your big-picture behavior constantly.\\n3. Reflect on past decisions\n      and strategies to refine your approach.\\n4. Every command has a cost, so be\n      smart and efficient. Aim to complete tasks in the least number of steps.\\n5.\n      Write all code to a file.\\n\\nYou should only respond in JSON format as described\n      below \\nResponse Format: \\n{\\n    \\\"thoughts\\\": {\\n        \\\"text\\\": \\\"thought\\\",\\n        \\\"reasoning\\\":\n      \\\"reasoning\\\",\\n        \\\"plan\\\": \\\"- short bulleted\\\\n- list that conveys\\\\n-\n      long-term plan\\\",\\n        \\\"criticism\\\": \\\"constructive self-criticism\\\",\\n        \\\"speak\\\":\n      \\\"thoughts summary to say to user\\\"\\n    },\\n    \\\"command\\\": {\\n        \\\"name\\\":\n      \\\"command name\\\",\\n        \\\"args\\\": {\\n            \\\"arg name\\\": \\\"value\\\"\\n        }\\n    }\\n}\n      \\nEnsure the response can be parsed by Python json.loads\"}, {\"role\": \"system\",\n      \"content\": \"The current time and date is Tue Jan  1 00:00:00 2000\"}, {\"role\":\n      \"system\", \"content\": \"This reminds you of these events from your past: \\nI was\n      created and nothing new has happened.\"}, {\"role\": \"user\", \"content\": \"Determine\n      which next command to use, and respond using the format specified above:\"},\n      {\"role\": \"assistant\", \"content\": \"{\\n    \\\"thoughts\\\": {\\n        \\\"text\\\":\n      \\\"I need to use the browse_website command to visit http://books.toscrape.com/catalogue/meditations_33/index.html\n      and find the price of the book.\\\",\\n        \\\"reasoning\\\": \\\"I can use the browse_website\n      command to visit the website and search for the price of the book by inspecting\n      the HTML code.\\\",\\n        \\\"plan\\\": \\\"- Use the browse_website command to visit\n      the website\\\\n- Inspect the HTML code to find the price of the book\\\\n- Write\n      the price to a file named ''browse_website.txt''\\\\n- Use the task_complete command\n      to complete the task\\\",\\n        \\\"criticism\\\": \\\"I need to be careful when\n      inspecting the HTML code to ensure I find the correct price.\\\",\\n        \\\"speak\\\":\n      \\\"I will use the browse_website command to visit the website and find the price\n      of the book.\\\"\\n    },\\n    \\\"command\\\": {\\n        \\\"name\\\": \\\"browse_website\\\",\\n        \\\"args\\\":\n      {\\n            \\\"url\\\": \\\"http://books.toscrape.com/catalogue/meditations_33/index.html\\\",\\n            \\\"question\\\":\n      \\\"What is the price of the book?\\\"\\n        }\\n    }\\n}\"}, {\"role\": \"system\",\n      \"content\": \"Command browse_website returned: Answer gathered from website: The\n      price of the book \\\"Meditations\\\" is \\u00a325.89, according to the text. \\n\n      \\n Links: [''Books to Scrape (http://books.toscrape.com/index.html)'', ''Home\n      (http://books.toscrape.com/index.html)'', ''Books (http://books.toscrape.com/catalogue/category/books_1/index.html)'',\n      ''Philosophy (http://books.toscrape.com/catalogue/category/books/philosophy_7/index.html)'',\n      '' (http://books.toscrape.com/catalogue/the-nicomachean-ethics_75/index.html)'']\"},\n      {\"role\": \"user\", \"content\": \"Determine which next command to use, and respond\n      using the format specified above:\"}], \"temperature\": 0, \"max_tokens\": 0}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '5682'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/chat/completions\n  response:\n    body:\n      string: !!binary |\n        H4sIAAAAAAAAA7xTyY7TQBC98xWtuuTSibKQzUc4ITQSSICQMLLa7UrcxO4yXRUSiPw1/AlfhryE\n        MJ65zpysrtd+S+n1BVwGEdjciC2rYrx+nc4/vf3xnRlPFb179avYbGgxff8Zs+0daKD0G1rp/5hY\n        KqsCxZEHDTagEcwgmq02i/litVrPNJSUYQER7CsZLybLsRxDSuPpYjoDDUc2e4ToAlWgspJE6ICe\n        IZrN11sNN/IbsF1pEBJT3EYv18tag83JWWSIvlygRL4SByoQIjDMjsV4aWySF/RNhEvslVIqBsnp\n        uM+FY4hUP+wBPEszjOGN8oiZElKn4ASV5Kiq4Cwq2rWHlOjQwEbtXIHKmxIzNUoDnRiTE6bsBCdy\n        ltEkBv2/RkDD5J3fX4Ws8erInUQrlgglLamlsjT+SVxUhfGdgbH6+NTiA20bnDjruByuGj0fQyNk\n        pBVoaR2rvmnK+XZsKQS0ojLXfCj8HIbjCs3hSn5yRfEs++0c1Prasp79Qckaks7cPTeDDCbsh/3s\n        gObujeKhlXs8w1p/eDTg6A4zJ6Z5ejxqFv7n93w52Wz/hWqD9fliX0OtYee84zzp2gwRsFAFGpzP\n        8AzRtP5av/gLAAD//wMAknh4rWwEAAA=\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7c23eceb0d9cc30c-VIE\n      Cache-Control:\n      - no-cache, must-revalidate\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Thu, 04 May 2023 21:44:42 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-model:\n      - gpt-3.5-turbo-0301\n      openai-organization:\n      - user-cbwy2y25pylufhkfs0la9nqe\n      openai-processing-ms:\n      - '11192'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3500'\n      x-ratelimit-limit-tokens:\n      - '90000'\n      x-ratelimit-remaining-requests:\n      - '3499'\n      x-ratelimit-remaining-tokens:\n      - '86479'\n      x-ratelimit-reset-requests:\n      - 17ms\n      x-ratelimit-reset-tokens:\n      - 2.346s\n      x-request-id:\n      - 8a46773fe4d416c50f9206f5ae9cacf5\n    status:\n      code: 200\n      message: OK\n- request:\n    body: '{\"model\": \"gpt-3.5-turbo\", \"messages\": [{\"role\": \"user\", \"content\": \"Your\n      task is to create a concise running summary of actions and information results\n      in the provided text, focusing on key and potentially important information\n      to remember.\\n\\nYou will receive the current summary and the your latest actions.\n      Combine them, adding relevant key information from the latest development in\n      1st person past tense and keeping the summary concise.\\n\\nSummary So Far:\\n\\\"\\\"\\\"\\n{''role'':\n      ''system'', ''content'': ''This reminds you of these events from your past:\n      \\\\nI was created and nothing new has happened.''}\\n\\\"\\\"\\\"\\n\\nLatest Development:\\n\\\"\\\"\\\"\\nNothing\n      new happened.\\n\\\"\\\"\\\"\\n\"}], \"temperature\": 0, \"max_tokens\": 0}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '713'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/chat/completions\n  response:\n    body:\n      string: !!binary |\n        H4sIAAAAAAAAA0SPXUsDMRBF3/0Vwzxny7bbVsmbHy9FQRFBRKRks9NuNMmEZLZVyv53KVT7ern3\n        cO4BXYcabW/EhuSry9t25vqbYTGs6ufX+m5nN/OXp/vH8LbrHlAht59k5bSYWA7JkziOqNBmMkId\n        6unyqpk1y+XVXGHgjjxq3CapmsmikiG3XNVNPUWFQzFbQn3AlDkkWQt/USyop7Na4Zn9nx9jYTH+\n        3JzXo0Lbs7NUUL8fMFD5o2b2hBpNKa6IiXJ05CgUj/7XBQyUnyIUFKwgkzXeg/RGYAV7U+B0B0zs\n        QHrKBL3ZEbREESJDpD10tCPPKVCUAsKQKXGWCY4KNy660q8zmcIRNRbhhApd7OgbdT1+jBe/AAAA\n        //8DAKdc/tB7AQAA\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7c23ed3eda7ec30c-VIE\n      Cache-Control:\n      - no-cache, must-revalidate\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Thu, 04 May 2023 21:44:46 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-model:\n      - gpt-3.5-turbo-0301\n      openai-organization:\n      - user-cbwy2y25pylufhkfs0la9nqe\n      openai-processing-ms:\n      - '1470'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3500'\n      x-ratelimit-limit-tokens:\n      - '90000'\n      x-ratelimit-remaining-requests:\n      - '3499'\n      x-ratelimit-remaining-tokens:\n      - '89839'\n      x-ratelimit-reset-requests:\n      - 17ms\n      x-ratelimit-reset-tokens:\n      - 107ms\n      x-request-id:\n      - c9cf33b227d0c6c46c3e92f14f731f25\n    status:\n      code: 200\n      message: OK\n- request:\n    body: '{\"model\": \"gpt-3.5-turbo\", \"messages\": [{\"role\": \"system\", \"content\": \"You\n      are browse_website-GPT, an AI designed to use the browse_website command to\n      visit http://books.toscrape.com/catalogue/meditations_33/index.html, answer\n      the question ''What is the price of the book?'' and write the price to a file\n      named \\\"browse_website.txt\\\", and use the task_complete command to complete\n      the task.\\nYour decisions must always be made independently without seeking\n      user assistance. Play to your strengths as an LLM and pursue simple strategies\n      with no legal complications.\\n\\nGOALS:\\n\\n1. Use the browse_website command\n      to visit http://books.toscrape.com/catalogue/meditations_33/index.html and answer\n      the question ''What is the price of the book?''\\n2. Write the price of the book\n      to a file named \\\"browse_website.txt\\\".\\n3. Use the task_complete command to\n      complete the task.\\n4. Do not use any other commands.\\n\\n\\nConstraints:\\n1.\n      ~4000 word limit for short term memory. Your short term memory is short, so\n      immediately save important information to files.\\n2. If you are unsure how you\n      previously did something or want to recall past events, thinking about similar\n      events will help you remember.\\n3. No user assistance\\n4. Exclusively use the\n      commands listed in double quotes e.g. \\\"command name\\\"\\n\\nCommands:\\n1. append_to_file:\n      Append to file, args: \\\"filename\\\": \\\"<filename>\\\", \\\"text\\\": \\\"<text>\\\"\\n2.\n      delete_file: Delete file, args: \\\"filename\\\": \\\"<filename>\\\"\\n3. list_files:\n      List Files in Directory, args: \\\"directory\\\": \\\"<directory>\\\"\\n4. read_file:\n      Read file, args: \\\"filename\\\": \\\"<filename>\\\"\\n5. write_to_file: Write to file,\n      args: \\\"filename\\\": \\\"<filename>\\\", \\\"text\\\": \\\"<text>\\\"\\n6. browse_website:\n      Browse Website, args: \\\"url\\\": \\\"<url>\\\", \\\"question\\\": \\\"<what_you_want_to_find_on_website>\\\"\\n7.\n      delete_agent: Delete GPT Agent, args: \\\"key\\\": \\\"<key>\\\"\\n8. get_hyperlinks:\n      Get text summary, args: \\\"url\\\": \\\"<url>\\\"\\n9. get_text_summary: Get text summary,\n      args: \\\"url\\\": \\\"<url>\\\", \\\"question\\\": \\\"<question>\\\"\\n10. list_agents: List\n      GPT Agents, args: () -> str\\n11. message_agent: Message GPT Agent, args: \\\"key\\\":\n      \\\"<key>\\\", \\\"message\\\": \\\"<message>\\\"\\n12. start_agent: Start GPT Agent, args:\n      \\\"name\\\": \\\"<name>\\\", \\\"task\\\": \\\"<short_task_desc>\\\", \\\"prompt\\\": \\\"<prompt>\\\"\\n13.\n      task_complete: Task Complete (Shutdown), args: \\\"reason\\\": \\\"<reason>\\\"\\n\\nResources:\\n1.\n      Internet access for searches and information gathering.\\n2. Long Term memory\n      management.\\n3. GPT-3.5 powered Agents for delegation of simple tasks.\\n4. File\n      output.\\n\\nPerformance Evaluation:\\n1. Continuously review and analyze your\n      actions to ensure you are performing to the best of your abilities.\\n2. Constructively\n      self-criticize your big-picture behavior constantly.\\n3. Reflect on past decisions\n      and strategies to refine your approach.\\n4. Every command has a cost, so be\n      smart and efficient. Aim to complete tasks in the least number of steps.\\n5.\n      Write all code to a file.\\n\\nYou should only respond in JSON format as described\n      below \\nResponse Format: \\n{\\n    \\\"thoughts\\\": {\\n        \\\"text\\\": \\\"thought\\\",\\n        \\\"reasoning\\\":\n      \\\"reasoning\\\",\\n        \\\"plan\\\": \\\"- short bulleted\\\\n- list that conveys\\\\n-\n      long-term plan\\\",\\n        \\\"criticism\\\": \\\"constructive self-criticism\\\",\\n        \\\"speak\\\":\n      \\\"thoughts summary to say to user\\\"\\n    },\\n    \\\"command\\\": {\\n        \\\"name\\\":\n      \\\"command name\\\",\\n        \\\"args\\\": {\\n            \\\"arg name\\\": \\\"value\\\"\\n        }\\n    }\\n}\n      \\nEnsure the response can be parsed by Python json.loads\"}, {\"role\": \"system\",\n      \"content\": \"The current time and date is Tue Jan  1 00:00:00 2000\"}, {\"role\":\n      \"system\", \"content\": \"This reminds you of these events from your past: \\nAs\n      a system, I recall that I was created and there have been no new developments\n      to report.\"}, {\"role\": \"user\", \"content\": \"Determine which next command to use,\n      and respond using the format specified above:\"}, {\"role\": \"assistant\", \"content\":\n      \"{\\n    \\\"thoughts\\\": {\\n        \\\"text\\\": \\\"I need to use the browse_website\n      command to visit http://books.toscrape.com/catalogue/meditations_33/index.html\n      and find the price of the book.\\\",\\n        \\\"reasoning\\\": \\\"I can use the browse_website\n      command to visit the website and search for the price of the book by inspecting\n      the HTML code.\\\",\\n        \\\"plan\\\": \\\"- Use the browse_website command to visit\n      the website\\\\n- Inspect the HTML code to find the price of the book\\\\n- Write\n      the price to a file named ''browse_website.txt''\\\\n- Use the task_complete command\n      to complete the task\\\",\\n        \\\"criticism\\\": \\\"I need to be careful when\n      inspecting the HTML code to ensure I find the correct price.\\\",\\n        \\\"speak\\\":\n      \\\"I will use the browse_website command to visit the website and find the price\n      of the book.\\\"\\n    },\\n    \\\"command\\\": {\\n        \\\"name\\\": \\\"browse_website\\\",\\n        \\\"args\\\":\n      {\\n            \\\"url\\\": \\\"http://books.toscrape.com/catalogue/meditations_33/index.html\\\",\\n            \\\"question\\\":\n      \\\"What is the price of the book?\\\"\\n        }\\n    }\\n}\"}, {\"role\": \"system\",\n      \"content\": \"Command browse_website returned: Answer gathered from website: The\n      price of the book \\\"Meditations\\\" is \\u00a325.89, according to the text. \\n\n      \\n Links: [''Books to Scrape (http://books.toscrape.com/index.html)'', ''Home\n      (http://books.toscrape.com/index.html)'', ''Books (http://books.toscrape.com/catalogue/category/books_1/index.html)'',\n      ''Philosophy (http://books.toscrape.com/catalogue/category/books/philosophy_7/index.html)'',\n      '' (http://books.toscrape.com/catalogue/the-nicomachean-ethics_75/index.html)'']\"},\n      {\"role\": \"user\", \"content\": \"Determine which next command to use, and respond\n      using the format specified above:\"}, {\"role\": \"assistant\", \"content\": \"{\\n    \\\"thoughts\\\":\n      {\\n        \\\"text\\\": \\\"I need to write the price of the book to a file named\n      ''browse_website.txt''.\\\",\\n        \\\"reasoning\\\": \\\"I can use the write_to_file\n      command to write the price of the book to a file named ''browse_website.txt''.\\\",\\n        \\\"plan\\\":\n      \\\"- Use the write_to_file command to write the price of the book to a file named\n      ''browse_website.txt''\\\",\\n        \\\"criticism\\\": \\\"I need to ensure that the\n      file is created in the correct directory.\\\",\\n        \\\"speak\\\": \\\"I will use\n      the write_to_file command to write the price of the book to a file named ''browse_website.txt''.\\\"\\n    },\\n    \\\"command\\\":\n      {\\n        \\\"name\\\": \\\"write_to_file\\\",\\n        \\\"args\\\": {\\n            \\\"filename\\\":\n      \\\"browse_website.txt\\\",\\n            \\\"text\\\": \\\"The price of the book ''Meditations''\n      is \\u00a325.89.\\\"\\n        }\\n    }\\n}\"}, {\"role\": \"system\", \"content\": \"Command\n      write_to_file returned: File written to successfully.\"}, {\"role\": \"user\", \"content\":\n      \"Determine which next command to use, and respond using the format specified\n      above:\"}], \"temperature\": 0, \"max_tokens\": 0}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '6824'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/chat/completions\n  response:\n    body:\n      string: !!binary |\n        H4sIAAAAAAAAA7yRQW/bMAyF7/sVAs9ykDiwk+m67ZAO2Gm9dB4CRWYt1bJkmHTbLfB/H1w7TZad\n        2sOuj+T3HskjuBIUGKvZNK1PNp8OaR3SOvN39jfpL9mj29x+3e4+N3f5DUiIhwc0PE8sTGxaj+xi\n        AAmmQ81Yglrl23W6zvNtLqGJJXpQULWcrBdZwn13iMlyvVyBhJ50haCO0HaxaXnPscZAoFZZupVw\n        hp8L6UcJHFn7s5Rnm0GCsdEZJFA/jtAgncBd9AgKNJEj1oHHmDEwhnGFYxGEEKIAtrGvLFMBSszi\n        XMBnHsUCdsLqRxRzJiwFWxSsqZaCotiJgKMWRU/4WtqfusexRoeXBrI9izI+hUUB8tKrQ00xuFD9\n        L8PW6zB5JeL23RTTOXbGUTOhvsWAVx3Uoq5PSz0579+WeUIN8vSsue2fXwXd4OTyF/YqjO6q6zdf\n        nn8CfNdUX1yeemOQ6L73/tdroJdQc7YiDDBIuHfBkd1PJFBAHFuQ4EKJz6CWw8/hwx8AAAD//wMA\n        YEZz+G8DAAA=\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7c23ed493d21c30c-VIE\n      Cache-Control:\n      - no-cache, must-revalidate\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Thu, 04 May 2023 21:44:53 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-model:\n      - gpt-3.5-turbo-0301\n      openai-organization:\n      - user-cbwy2y25pylufhkfs0la9nqe\n      openai-processing-ms:\n      - '7454'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3500'\n      x-ratelimit-limit-tokens:\n      - '90000'\n      x-ratelimit-remaining-requests:\n      - '3499'\n      x-ratelimit-remaining-tokens:\n      - '86479'\n      x-ratelimit-reset-requests:\n      - 17ms\n      x-ratelimit-reset-tokens:\n      - 2.347s\n      x-request-id:\n      - 09cc7d22955a6d026a3d8c433a65c28e\n    status:\n      code: 200\n      message: OK\nversion: 1\n"
  },
  {
    "path": "tests/integration/goal_oriented/cassettes/test_write_file/test_write_file.yaml",
    "content": "interactions:\n- request:\n    body: '{\"model\": \"gpt-3.5-turbo\", \"messages\": [{\"role\": \"system\", \"content\": \"You\n      are write_to_file-GPT, an AI designed to use the write_to_file command to write\n      ''Hello World'' into a file named \\\"hello_world.txt\\\" and then use the task_complete\n      command to complete the task.\\nYour decisions must always be made independently\n      without seeking user assistance. Play to your strengths as an LLM and pursue\n      simple strategies with no legal complications.\\n\\nGOALS:\\n\\n1. Use the write_to_file\n      command to write ''Hello World'' into a file named \\\"hello_world.txt\\\".\\n2.\n      Use the task_complete command to complete the task.\\n3. Do not use any other\n      commands.\\n\\n\\nConstraints:\\n1. ~4000 word limit for short term memory. Your\n      short term memory is short, so immediately save important information to files.\\n2.\n      If you are unsure how you previously did something or want to recall past events,\n      thinking about similar events will help you remember.\\n3. No user assistance\\n4.\n      Exclusively use the commands listed in double quotes e.g. \\\"command name\\\"\\n\\nCommands:\\n1.\n      append_to_file: Append to file, args: \\\"filename\\\": \\\"<filename>\\\", \\\"text\\\":\n      \\\"<text>\\\"\\n2. delete_file: Delete file, args: \\\"filename\\\": \\\"<filename>\\\"\\n3.\n      list_files: List Files in Directory, args: \\\"directory\\\": \\\"<directory>\\\"\\n4.\n      read_file: Read file, args: \\\"filename\\\": \\\"<filename>\\\"\\n5. write_to_file:\n      Write to file, args: \\\"filename\\\": \\\"<filename>\\\", \\\"text\\\": \\\"<text>\\\"\\n6.\n      delete_agent: Delete GPT Agent, args: \\\"key\\\": \\\"<key>\\\"\\n7. get_hyperlinks:\n      Get text summary, args: \\\"url\\\": \\\"<url>\\\"\\n8. get_text_summary: Get text summary,\n      args: \\\"url\\\": \\\"<url>\\\", \\\"question\\\": \\\"<question>\\\"\\n9. list_agents: List\n      GPT Agents, args: () -> str\\n10. message_agent: Message GPT Agent, args: \\\"key\\\":\n      \\\"<key>\\\", \\\"message\\\": \\\"<message>\\\"\\n11. start_agent: Start GPT Agent, args:\n      \\\"name\\\": \\\"<name>\\\", \\\"task\\\": \\\"<short_task_desc>\\\", \\\"prompt\\\": \\\"<prompt>\\\"\\n12.\n      Task Complete (Shutdown): \\\"task_complete\\\", args: \\\"reason\\\": \\\"<reason>\\\"\\n\\nResources:\\n1.\n      Internet access for searches and information gathering.\\n2. Long Term memory\n      management.\\n3. GPT-3.5 powered Agents for delegation of simple tasks.\\n4. File\n      output.\\n\\nPerformance Evaluation:\\n1. Continuously review and analyze your\n      actions to ensure you are performing to the best of your abilities.\\n2. Constructively\n      self-criticize your big-picture behavior constantly.\\n3. Reflect on past decisions\n      and strategies to refine your approach.\\n4. Every command has a cost, so be\n      smart and efficient. Aim to complete tasks in the least number of steps.\\n5.\n      Write all code to a file.\\n\\nYou should only respond in JSON format as described\n      below \\nResponse Format: \\n{\\n    \\\"thoughts\\\": {\\n        \\\"text\\\": \\\"thought\\\",\\n        \\\"reasoning\\\":\n      \\\"reasoning\\\",\\n        \\\"plan\\\": \\\"- short bulleted\\\\n- list that conveys\\\\n-\n      long-term plan\\\",\\n        \\\"criticism\\\": \\\"constructive self-criticism\\\",\\n        \\\"speak\\\":\n      \\\"thoughts summary to say to user\\\"\\n    },\\n    \\\"command\\\": {\\n        \\\"name\\\":\n      \\\"command name\\\",\\n        \\\"args\\\": {\\n            \\\"arg name\\\": \\\"value\\\"\\n        }\\n    }\\n}\n      \\nEnsure the response can be parsed by Python json.loads\"}, {\"role\": \"system\",\n      \"content\": \"The current time and date is Tue Jan  1 00:00:00 2000\"}, {\"role\":\n      \"user\", \"content\": \"Determine which next command to use, and respond using the\n      format specified above:\"}], \"temperature\": 0, \"max_tokens\": 0}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '3410'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/chat/completions\n  response:\n    body:\n      string: !!binary |\n        H4sIAAAAAAAAA7ySQY/aQAyF7/0Vli+5DAgWFmiO7aU9VlWLVk2FZieGDEzGsxlHUKH89yokLGwq\n        9dZe/eznzzPvjDbHFE2hxZTBjZYffL3e0+HxhfmjfFnPwvdCvxRh//TEOSrk5z0Z6SfGhsvgSCx7\n        VGgq0kI5ptPFajaZL1cPE4Ul5+QwxV2Q0Wz8OJK6eubRZDaZosI66h1hesZQcRlkI3wgHzFdLh4U\n        3rxf69PVXKGwaPdaej9fNApNwdZQxPTHGUuKV9uKHWGKOkYbRXtpIdkL+faAc+YBADKUgutdITHD\n        FPpiL9BJ2mKGn8ET5SAMdSSQguBYWaGN8GZrHYHhstT+0nARIPlEzjGsuXJ5AtYLg4ZLq9cl5ZAU\n        rb45tvpYTpKMM1T3uyvSkb31uw7gq/WG4IbRbdEQAxm7tQZa1vs96i+UNl7EkqOADqHiUFktBOyp\n        P3FIE5z2HcgIvv2nFzCVFWtsLK9fkLNPBCIRaP8LbIw1RThaKUAKG6FlHHrEQPpwnT9a5/7l/3WL\n        G3XNVW/6R6xah47pDcQAXVe7YSI7oe29WQw43pgMU3x305X2QtyDZ77BRuHWehuLTRdATDEKB1Ro\n        fU4nTCfNz+bdbwAAAP//AwAsTU8qNQQAAA==\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7c11ea4fb82bfade-SJC\n      Cache-Control:\n      - no-cache, must-revalidate\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Tue, 02 May 2023 17:17:12 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-model:\n      - gpt-3.5-turbo-0301\n      openai-organization:\n      - user-adtx4fhfg1qsiyzdoaxciooj\n      openai-processing-ms:\n      - '11488'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3500'\n      x-ratelimit-limit-tokens:\n      - '90000'\n      x-ratelimit-remaining-requests:\n      - '3499'\n      x-ratelimit-remaining-tokens:\n      - '86497'\n      x-ratelimit-reset-requests:\n      - 17ms\n      x-ratelimit-reset-tokens:\n      - 2.335s\n      x-request-id:\n      - 81a8552ed38d0037b7b7c23664f5ae2b\n    status:\n      code: 200\n      message: OK\n- request:\n    body: '{\"model\": \"gpt-3.5-turbo\", \"messages\": [{\"role\": \"user\", \"content\": \"Your\n      task is to create a concise running summary of actions and information results\n      in the provided text, focusing on key and potentially important information\n      to remember.\\n\\nYou will receive the current summary and the your latest actions.\n      Combine them, adding relevant key information from the latest development in\n      1st person past tense and keeping the summary concise.\\n\\nSummary So Far:\\n\\\"\\\"\\\"\\nI\n      was created.\\n\\\"\\\"\\\"\\n\\nLatest Development:\\n\\\"\\\"\\\"\\nNothing new happened.\\n\\\"\\\"\\\"\\n\"}],\n      \"temperature\": 0, \"max_tokens\": 0}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '599'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/chat/completions\n  response:\n    body:\n      string: !!binary |\n        H4sIAAAAAAAAA0SOQU/CQBBG7/6K5jtvSUsRcI+KMd6MeNIYsm2HdqGdWbtD0JD+d0OCcn3Je3kn\n        +BoWVeu06kOXLu75sH9arV+6t9V0/vW6e3jfCpe0fvTNDwyk3FGlF2NSSR86Ui8Mg2ogp1TD5vNl\n        kc0Wy2Jm0EtNHSyaoGkxuU31MJSSZkWWw+AQXUOwJ4RB+qAblT1xhL2bGlzTV2ygoq77B3mWjwZV\n        K76iCPtxQk/xrzlIR7BwMfqojvV8KKzE5/vn5OhicjlOHNcJi7aem4TpmLQuJq0LgZjqCUaDrWcf\n        281ALgrDIqoEGHiu6Rs2Gz/Hm18AAAD//wMA1rZZUUkBAAA=\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7c11eaa7f982fade-SJC\n      Cache-Control:\n      - no-cache, must-revalidate\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Tue, 02 May 2023 17:17:15 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-model:\n      - gpt-3.5-turbo-0301\n      openai-organization:\n      - user-adtx4fhfg1qsiyzdoaxciooj\n      openai-processing-ms:\n      - '1025'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3500'\n      x-ratelimit-limit-tokens:\n      - '90000'\n      x-ratelimit-remaining-requests:\n      - '3499'\n      x-ratelimit-remaining-tokens:\n      - '89866'\n      x-ratelimit-reset-requests:\n      - 17ms\n      x-ratelimit-reset-tokens:\n      - 88ms\n      x-request-id:\n      - dcfcb7a7f05897ff8d7924daba89388c\n    status:\n      code: 200\n      message: OK\n- request:\n    body: '{\"model\": \"gpt-3.5-turbo\", \"messages\": [{\"role\": \"system\", \"content\": \"You\n      are write_to_file-GPT, an AI designed to use the write_to_file command to write\n      ''Hello World'' into a file named \\\"hello_world.txt\\\" and then use the task_complete\n      command to complete the task.\\nYour decisions must always be made independently\n      without seeking user assistance. Play to your strengths as an LLM and pursue\n      simple strategies with no legal complications.\\n\\nGOALS:\\n\\n1. Use the write_to_file\n      command to write ''Hello World'' into a file named \\\"hello_world.txt\\\".\\n2.\n      Use the task_complete command to complete the task.\\n3. Do not use any other\n      commands.\\n\\n\\nConstraints:\\n1. ~4000 word limit for short term memory. Your\n      short term memory is short, so immediately save important information to files.\\n2.\n      If you are unsure how you previously did something or want to recall past events,\n      thinking about similar events will help you remember.\\n3. No user assistance\\n4.\n      Exclusively use the commands listed in double quotes e.g. \\\"command name\\\"\\n\\nCommands:\\n1.\n      append_to_file: Append to file, args: \\\"filename\\\": \\\"<filename>\\\", \\\"text\\\":\n      \\\"<text>\\\"\\n2. delete_file: Delete file, args: \\\"filename\\\": \\\"<filename>\\\"\\n3.\n      list_files: List Files in Directory, args: \\\"directory\\\": \\\"<directory>\\\"\\n4.\n      read_file: Read file, args: \\\"filename\\\": \\\"<filename>\\\"\\n5. write_to_file:\n      Write to file, args: \\\"filename\\\": \\\"<filename>\\\", \\\"text\\\": \\\"<text>\\\"\\n6.\n      delete_agent: Delete GPT Agent, args: \\\"key\\\": \\\"<key>\\\"\\n7. get_hyperlinks:\n      Get text summary, args: \\\"url\\\": \\\"<url>\\\"\\n8. get_text_summary: Get text summary,\n      args: \\\"url\\\": \\\"<url>\\\", \\\"question\\\": \\\"<question>\\\"\\n9. list_agents: List\n      GPT Agents, args: () -> str\\n10. message_agent: Message GPT Agent, args: \\\"key\\\":\n      \\\"<key>\\\", \\\"message\\\": \\\"<message>\\\"\\n11. start_agent: Start GPT Agent, args:\n      \\\"name\\\": \\\"<name>\\\", \\\"task\\\": \\\"<short_task_desc>\\\", \\\"prompt\\\": \\\"<prompt>\\\"\\n12.\n      Task Complete (Shutdown): \\\"task_complete\\\", args: \\\"reason\\\": \\\"<reason>\\\"\\n\\nResources:\\n1.\n      Internet access for searches and information gathering.\\n2. Long Term memory\n      management.\\n3. GPT-3.5 powered Agents for delegation of simple tasks.\\n4. File\n      output.\\n\\nPerformance Evaluation:\\n1. Continuously review and analyze your\n      actions to ensure you are performing to the best of your abilities.\\n2. Constructively\n      self-criticize your big-picture behavior constantly.\\n3. Reflect on past decisions\n      and strategies to refine your approach.\\n4. Every command has a cost, so be\n      smart and efficient. Aim to complete tasks in the least number of steps.\\n5.\n      Write all code to a file.\\n\\nYou should only respond in JSON format as described\n      below \\nResponse Format: \\n{\\n    \\\"thoughts\\\": {\\n        \\\"text\\\": \\\"thought\\\",\\n        \\\"reasoning\\\":\n      \\\"reasoning\\\",\\n        \\\"plan\\\": \\\"- short bulleted\\\\n- list that conveys\\\\n-\n      long-term plan\\\",\\n        \\\"criticism\\\": \\\"constructive self-criticism\\\",\\n        \\\"speak\\\":\n      \\\"thoughts summary to say to user\\\"\\n    },\\n    \\\"command\\\": {\\n        \\\"name\\\":\n      \\\"command name\\\",\\n        \\\"args\\\": {\\n            \\\"arg name\\\": \\\"value\\\"\\n        }\\n    }\\n}\n      \\nEnsure the response can be parsed by Python json.loads\"}, {\"role\": \"system\",\n      \"content\": \"The current time and date is Tue Jan  1 00:00:00 2000\"}, {\"role\":\n      \"system\", \"content\": \"This reminds you of these events from your past: \\nI was\n      created and nothing new has happened.\"}, {\"role\": \"user\", \"content\": \"Determine\n      which next command to use, and respond using the format specified above:\"},\n      {\"role\": \"assistant\", \"content\": \"{\\n    \\\"thoughts\\\": {\\n        \\\"text\\\":\n      \\\"I need to use the write_to_file command to write ''Hello World'' into a file\n      named ''hello_world.txt''.\\\",\\n        \\\"reasoning\\\": \\\"Since I need to write\n      a specific text into a file, the write_to_file command is the most appropriate\n      one to use.\\\",\\n        \\\"plan\\\": \\\"- Use the write_to_file command to write\n      ''Hello World'' into a file named ''hello_world.txt''.\\\",\\n        \\\"criticism\\\":\n      \\\"I don''t see any issues with this plan.\\\",\\n        \\\"speak\\\": \\\"I will use\n      the write_to_file command to write ''Hello World'' into a file named ''hello_world.txt''.\\\"\\n    },\\n    \\\"command\\\":\n      {\\n        \\\"name\\\": \\\"write_to_file\\\",\\n        \\\"args\\\": {\\n            \\\"filename\\\":\n      \\\"hello_world.txt\\\",\\n            \\\"text\\\": \\\"Hello World\\\"\\n        }\\n    }\\n}\"},\n      {\"role\": \"system\", \"content\": \"Command write_to_file returned: File written\n      to successfully.\"}, {\"role\": \"user\", \"content\": \"Determine which next command\n      to use, and respond using the format specified above:\"}], \"temperature\": 0,\n      \"max_tokens\": 0}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '4576'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/chat/completions\n  response:\n    body:\n      string: !!binary |\n        H4sIAAAAAAAAA7SST2/TQBDF73yK0Vxy2UQxpknwsRKoESoXFIGEq2i7nthL1ruuZ0xSonx35NhO\n        SrgVcZ0/b35v9x3QZpigKbSYsnLj+a1vytzef1x9e7qp71a/dFR9+sD389Xbp1tUGB5/kJF+Y2JC\n        WTkSGzwqNDVpoQyTaLaIp+/mi3imsAwZOUwwr2QcT27G0tSPYTyNpxEqbFjnhMkBqzqUlawlbMkz\n        JtE0ihVexC+NRaxQgmh3KUXvZ0eFpgjWEGPy/YAl8SBcB0eYoGa2LNpLixm8kG8tHFIPAJCiFKHJ\n        C+EUE+iLfYP20hZT/Bx2IIUWWEKhfxLsaitCHkZ35FyAr6F22QislwAaNtYReF1SBqOi7a93bX8i\n        exkpWIInykACNEwgBYFo3q57uwQmlKX2p4FzbZiapKheAtakOXjr847yi/WGBsRhOTtvQ9icwK3P\n        /zO49Zk1+gSu5XLf8pnq2knltO9MjGH1z+9iWpfGctlJLiELfiTARKD9M1jmhhh2VgqQwjK01681\n        uCK9HfZ31rnX/VcneVRD2Prxv7LWPnt37Q/5Kyhd59cxfZmEAfcUAG6MIeZN49zz6wN7tnCy0btJ\n        /RGPCjfWWy7W3W1MkCVUqND6jPaYTI8Pxze/AQAA//8DAOv7y1VhBAAA\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7c11eaaf0abffade-SJC\n      Cache-Control:\n      - no-cache, must-revalidate\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Tue, 02 May 2023 17:17:26 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-model:\n      - gpt-3.5-turbo-0301\n      openai-organization:\n      - user-adtx4fhfg1qsiyzdoaxciooj\n      openai-processing-ms:\n      - '10848'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3500'\n      x-ratelimit-limit-tokens:\n      - '90000'\n      x-ratelimit-remaining-requests:\n      - '3499'\n      x-ratelimit-remaining-tokens:\n      - '86485'\n      x-ratelimit-reset-requests:\n      - 17ms\n      x-ratelimit-reset-tokens:\n      - 2.342s\n      x-request-id:\n      - e0a52aa6b569cb67dbbb8e6098e31231\n    status:\n      code: 200\n      message: OK\n- request:\n    body: '{\"model\": \"gpt-3.5-turbo\", \"messages\": [{\"role\": \"system\", \"content\": \"You\n      are write_to_file-GPT, an AI designed to use the write_to_file command to write\n      ''Hello World'' into a file named \\\"hello_world.txt\\\" and then use the task_complete\n      command to complete the task.\\nYour decisions must always be made independently\n      without seeking user assistance. Play to your strengths as an LLM and pursue\n      simple strategies with no legal complications.\\n\\nGOALS:\\n\\n1. Use the write_to_file\n      command to write ''Hello World'' into a file named \\\"hello_world.txt\\\".\\n2.\n      Use the task_complete command to complete the task.\\n3. Do not use any other\n      commands.\\n\\n\\nConstraints:\\n1. ~4000 word limit for short term memory. Your\n      short term memory is short, so immediately save important information to files.\\n2.\n      If you are unsure how you previously did something or want to recall past events,\n      thinking about similar events will help you remember.\\n3. No user assistance\\n4.\n      Exclusively use the commands listed in double quotes e.g. \\\"command name\\\"\\n\\nCommands:\\n1.\n      append_to_file: Append to file, args: \\\"filename\\\": \\\"<filename>\\\", \\\"text\\\":\n      \\\"<text>\\\"\\n2. delete_file: Delete file, args: \\\"filename\\\": \\\"<filename>\\\"\\n3.\n      list_files: List Files in Directory, args: \\\"directory\\\": \\\"<directory>\\\"\\n4.\n      read_file: Read file, args: \\\"filename\\\": \\\"<filename>\\\"\\n5. write_to_file:\n      Write to file, args: \\\"filename\\\": \\\"<filename>\\\", \\\"text\\\": \\\"<text>\\\"\\n6.\n      delete_agent: Delete GPT Agent, args: \\\"key\\\": \\\"<key>\\\"\\n7. get_hyperlinks:\n      Get text summary, args: \\\"url\\\": \\\"<url>\\\"\\n8. get_text_summary: Get text summary,\n      args: \\\"url\\\": \\\"<url>\\\", \\\"question\\\": \\\"<question>\\\"\\n9. list_agents: List\n      GPT Agents, args: () -> str\\n10. message_agent: Message GPT Agent, args: \\\"key\\\":\n      \\\"<key>\\\", \\\"message\\\": \\\"<message>\\\"\\n11. start_agent: Start GPT Agent, args:\n      \\\"name\\\": \\\"<name>\\\", \\\"task\\\": \\\"<short_task_desc>\\\", \\\"prompt\\\": \\\"<prompt>\\\"\\n12.\n      task_complete: Task Complete (Shutdown), args: \\\"reason\\\": \\\"<reason>\\\"\\n\\nResources:\\n1.\n      Internet access for searches and information gathering.\\n2. Long Term memory\n      management.\\n3. GPT-3.5 powered Agents for delegation of simple tasks.\\n4. File\n      output.\\n\\nPerformance Evaluation:\\n1. Continuously review and analyze your\n      actions to ensure you are performing to the best of your abilities.\\n2. Constructively\n      self-criticize your big-picture behavior constantly.\\n3. Reflect on past decisions\n      and strategies to refine your approach.\\n4. Every command has a cost, so be\n      smart and efficient. Aim to complete tasks in the least number of steps.\\n5.\n      Write all code to a file.\\n\\nYou should only respond in JSON format as described\n      below \\nResponse Format: \\n{\\n    \\\"thoughts\\\": {\\n        \\\"text\\\": \\\"thought\\\",\\n        \\\"reasoning\\\":\n      \\\"reasoning\\\",\\n        \\\"plan\\\": \\\"- short bulleted\\\\n- list that conveys\\\\n-\n      long-term plan\\\",\\n        \\\"criticism\\\": \\\"constructive self-criticism\\\",\\n        \\\"speak\\\":\n      \\\"thoughts summary to say to user\\\"\\n    },\\n    \\\"command\\\": {\\n        \\\"name\\\":\n      \\\"command name\\\",\\n        \\\"args\\\": {\\n            \\\"arg name\\\": \\\"value\\\"\\n        }\\n    }\\n}\n      \\nEnsure the response can be parsed by Python json.loads\"}, {\"role\": \"system\",\n      \"content\": \"The current time and date is Tue Jan  1 00:00:00 2000\"}, {\"role\":\n      \"user\", \"content\": \"Determine which next command to use, and respond using the\n      format specified above:\"}], \"temperature\": 0, \"max_tokens\": 0}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '3406'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/chat/completions\n  response:\n    body:\n      string: !!binary |\n        H4sIAAAAAAAAA7yTT4/TQAzF73wKy5de0iqh0O3mthwQPYAEdMUuBFWzE7cZOhmHGUctVPnuKEn/\n        7AZxQnD1c9772eMc0OSYoi6U6LKy46tXP+5vbpZhoT+/u329nCc/39692H58PzUf7q8xQn74RlqO\n        X0w0l5UlMewwQu1JCeWYJrP5NJ7Pr5J5hCXnZDHFTSXj6eTlWGr/wON4GicYYR3UhjA9YOW5rGQl\n        vCUXML2aJRFevM/153EcobAoey5dz5ImQl2w0RQw/XLAksLJ1rMlTFGFYIIoJy0kOyHXDnDIHABA\n        hlJwvSkkZJjCsXgUaC9tMcMFOKIchKEOBFIQ7LwRWgmv1sYSaC5L5bqGToDRG7KW4RN7m4/AOGFQ\n        0LU6VVIOo6LVV7tWn8heRpMMo8fZnlRgZ9ymB1gWBKLCFjx9r42nACX9RVoEHe0f5zChE1VVea68\n        UXKR1uxBirZBhe2QurLK9cBjuP1Pm9LeiNEmlMOnIhdq3zIogcX54TR7T1q6iDah3wTt5YIk3HW2\n        HcOwUJHanoJ2xtp/eRB9cBOdDvVo+tudtg490xOIAbrym+GJ98JpE73FgOOJyfC3eDTTibYjPoJn\n        rsEmwrVxJhSr/qIxxSBcYYTG5bTHNG6+Ns9+AQAA//8DAAaMC/aGBAAA\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7c15d0c86db14665-DFW\n      Cache-Control:\n      - no-cache, must-revalidate\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Wed, 03 May 2023 04:38:50 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-model:\n      - gpt-3.5-turbo-0301\n      openai-organization:\n      - significant-gravitas\n      openai-processing-ms:\n      - '11864'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3500'\n      x-ratelimit-limit-tokens:\n      - '90000'\n      x-ratelimit-remaining-requests:\n      - '3499'\n      x-ratelimit-remaining-tokens:\n      - '86496'\n      x-ratelimit-reset-requests:\n      - 17ms\n      x-ratelimit-reset-tokens:\n      - 2.335s\n      x-request-id:\n      - 5d9f1c3b077997ea564ea7088eca733f\n    status:\n      code: 200\n      message: OK\n- request:\n    body: '{\"model\": \"gpt-3.5-turbo\", \"messages\": [{\"role\": \"system\", \"content\": \"You\n      are write_to_file-GPT, an AI designed to use the write_to_file command to write\n      ''Hello World'' into a file named \\\"hello_world.txt\\\" and then use the task_complete\n      command to complete the task.\\nYour decisions must always be made independently\n      without seeking user assistance. Play to your strengths as an LLM and pursue\n      simple strategies with no legal complications.\\n\\nGOALS:\\n\\n1. Use the write_to_file\n      command to write ''Hello World'' into a file named \\\"hello_world.txt\\\".\\n2.\n      Use the task_complete command to complete the task.\\n3. Do not use any other\n      commands.\\n\\n\\nConstraints:\\n1. ~4000 word limit for short term memory. Your\n      short term memory is short, so immediately save important information to files.\\n2.\n      If you are unsure how you previously did something or want to recall past events,\n      thinking about similar events will help you remember.\\n3. No user assistance\\n4.\n      Exclusively use the commands listed in double quotes e.g. \\\"command name\\\"\\n\\nCommands:\\n1.\n      append_to_file: Append to file, args: \\\"filename\\\": \\\"<filename>\\\", \\\"text\\\":\n      \\\"<text>\\\"\\n2. delete_file: Delete file, args: \\\"filename\\\": \\\"<filename>\\\"\\n3.\n      list_files: List Files in Directory, args: \\\"directory\\\": \\\"<directory>\\\"\\n4.\n      read_file: Read file, args: \\\"filename\\\": \\\"<filename>\\\"\\n5. write_to_file:\n      Write to file, args: \\\"filename\\\": \\\"<filename>\\\", \\\"text\\\": \\\"<text>\\\"\\n6.\n      delete_agent: Delete GPT Agent, args: \\\"key\\\": \\\"<key>\\\"\\n7. get_hyperlinks:\n      Get text summary, args: \\\"url\\\": \\\"<url>\\\"\\n8. get_text_summary: Get text summary,\n      args: \\\"url\\\": \\\"<url>\\\", \\\"question\\\": \\\"<question>\\\"\\n9. list_agents: List\n      GPT Agents, args: () -> str\\n10. message_agent: Message GPT Agent, args: \\\"key\\\":\n      \\\"<key>\\\", \\\"message\\\": \\\"<message>\\\"\\n11. start_agent: Start GPT Agent, args:\n      \\\"name\\\": \\\"<name>\\\", \\\"task\\\": \\\"<short_task_desc>\\\", \\\"prompt\\\": \\\"<prompt>\\\"\\n12.\n      task_complete: Task Complete (Shutdown), args: \\\"reason\\\": \\\"<reason>\\\"\\n\\nResources:\\n1.\n      Internet access for searches and information gathering.\\n2. Long Term memory\n      management.\\n3. GPT-3.5 powered Agents for delegation of simple tasks.\\n4. File\n      output.\\n\\nPerformance Evaluation:\\n1. Continuously review and analyze your\n      actions to ensure you are performing to the best of your abilities.\\n2. Constructively\n      self-criticize your big-picture behavior constantly.\\n3. Reflect on past decisions\n      and strategies to refine your approach.\\n4. Every command has a cost, so be\n      smart and efficient. Aim to complete tasks in the least number of steps.\\n5.\n      Write all code to a file.\\n\\nYou should only respond in JSON format as described\n      below \\nResponse Format: \\n{\\n    \\\"thoughts\\\": {\\n        \\\"text\\\": \\\"thought\\\",\\n        \\\"reasoning\\\":\n      \\\"reasoning\\\",\\n        \\\"plan\\\": \\\"- short bulleted\\\\n- list that conveys\\\\n-\n      long-term plan\\\",\\n        \\\"criticism\\\": \\\"constructive self-criticism\\\",\\n        \\\"speak\\\":\n      \\\"thoughts summary to say to user\\\"\\n    },\\n    \\\"command\\\": {\\n        \\\"name\\\":\n      \\\"command name\\\",\\n        \\\"args\\\": {\\n            \\\"arg name\\\": \\\"value\\\"\\n        }\\n    }\\n}\n      \\nEnsure the response can be parsed by Python json.loads\"}, {\"role\": \"system\",\n      \"content\": \"The current time and date is Tue Jan  1 00:00:00 2000\"}, {\"role\":\n      \"system\", \"content\": \"This reminds you of these events from your past: \\nI was\n      created and nothing new has happened.\"}, {\"role\": \"user\", \"content\": \"Determine\n      which next command to use, and respond using the format specified above:\"},\n      {\"role\": \"assistant\", \"content\": \"{\\n    \\\"thoughts\\\": {\\n        \\\"text\\\":\n      \\\"I need to use the write_to_file command to write ''Hello World'' into a file\n      named ''hello_world.txt''.\\\",\\n        \\\"reasoning\\\": \\\"The task requires me\n      to write ''Hello World'' into a file named ''hello_world.txt'', and the write_to_file\n      command is the appropriate command for this task.\\\",\\n        \\\"plan\\\": \\\"-\n      Use the write_to_file command to write ''Hello World'' into a file named ''hello_world.txt''.\\\",\\n        \\\"criticism\\\":\n      \\\"I need to ensure that I use the correct filename and text to write to the\n      file.\\\",\\n        \\\"speak\\\": \\\"I will use the write_to_file command to write\n      ''Hello World'' into a file named ''hello_world.txt''.\\\"\\n    },\\n    \\\"command\\\":\n      {\\n        \\\"name\\\": \\\"write_to_file\\\",\\n        \\\"args\\\": {\\n            \\\"filename\\\":\n      \\\"hello_world.txt\\\",\\n            \\\"text\\\": \\\"Hello World\\\"\\n        }\\n    }\\n}\"},\n      {\"role\": \"system\", \"content\": \"Command write_to_file returned: File written\n      to successfully.\"}, {\"role\": \"user\", \"content\": \"Determine which next command\n      to use, and respond using the format specified above:\"}], \"temperature\": 0,\n      \"max_tokens\": 0}'\n    headers:\n      Accept:\n      - '*/*'\n      Accept-Encoding:\n      - gzip, deflate\n      Connection:\n      - keep-alive\n      Content-Length:\n      - '4653'\n      Content-Type:\n      - application/json\n    method: POST\n    uri: https://api.openai.com/v1/chat/completions\n  response:\n    body:\n      string: !!binary |\n        H4sIAAAAAAAAA7RTyW7bMBC99ysGc/GFNmQbbVwdiwapgQLd0hZBVBgMNZZYU6RKjrzA0L8XtKQk\n        TReg242YefMWcnhEnWOKqpSsqtqMz54drl5V+Z6W/OaDfHlhzpMNmefnh4vX5i0KdDefSXE/MVGu\n        qg2xdhYFKk+SKcd0+mQxTxaLs/lMYOVyMphiUfN4Pnk85sbfuHEyT6YosAmyIEyPWHtX1bxityEb\n        MJ0ms4XAO/LbxiyZCmTH0txhZ7OnrUBVOq0oYHp9xIrCQOydIUxRhqADS8vRprNMNkY4ZhYAIEMu\n        XVOUHDJMoS/2DdpzLGa4hFJuCUKjFIWwbow5wM5rZrIwekHGOPjovMlHoC07kLDWhsDKinIYlbG/\n        2sX+hPc8msBlSWBpzxCYatAB2EETCLgkYBk2qz48gXJVJW0eAbe1ATXJUNy360kGZ7UtOs+XPQw8\n        fWm0pwAVRZ7om37fNZxslGR/YATeaasIfnVL7E7wqCBOp3+fvzbSdtHH8P6v2ZTXrJUO1bABlug0\n        STY0Ps5JhiXU3m11TiBhK43OoXsEWDs/SGhb/FQk1CQ3g8BOG/Nn19BRtmLY6B7+3ULHp+3UvqF/\n        YEr64uFfuL9g/+NHDBFOMfo0mW2xFbjWVody1WljioFdjQK1zWmPadJ+ah99BQAA//8DAMo52K3G\n        BAAA\n    headers:\n      CF-Cache-Status:\n      - DYNAMIC\n      CF-RAY:\n      - 7c15d120ec8f4665-DFW\n      Cache-Control:\n      - no-cache, must-revalidate\n      Connection:\n      - keep-alive\n      Content-Encoding:\n      - gzip\n      Content-Type:\n      - application/json\n      Date:\n      - Wed, 03 May 2023 04:39:04 GMT\n      Server:\n      - cloudflare\n      access-control-allow-origin:\n      - '*'\n      alt-svc:\n      - h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\n      openai-model:\n      - gpt-3.5-turbo-0301\n      openai-organization:\n      - significant-gravitas\n      openai-processing-ms:\n      - '12271'\n      openai-version:\n      - '2020-10-01'\n      strict-transport-security:\n      - max-age=15724800; includeSubDomains\n      x-ratelimit-limit-requests:\n      - '3500'\n      x-ratelimit-limit-tokens:\n      - '90000'\n      x-ratelimit-remaining-requests:\n      - '3499'\n      x-ratelimit-remaining-tokens:\n      - '86481'\n      x-ratelimit-reset-requests:\n      - 17ms\n      x-ratelimit-reset-tokens:\n      - 2.346s\n      x-request-id:\n      - a8c02e37e5af0c851759aa261f20f701\n    status:\n      code: 200\n      message: OK\nversion: 1\n"
  },
  {
    "path": "tests/integration/goal_oriented/goal_oriented_tasks.md",
    "content": "If the goal oriented task pipeline fails, it means: \n- you somehow changed the way the system prompt is generated \n- or you broke autogpt.\n\nTo know which one, you can run the following command: \n```bash\npytest -s -k tests/integration/goal_oriented\n\nIf the test is successul, it will record new cassettes in VCR. Then you can just push these to your branch and the pipeline\nwill pass\n"
  },
  {
    "path": "tests/integration/goal_oriented/test_browse_website.py",
    "content": "import pytest\r\n\r\nfrom autogpt.agent import Agent\r\nfrom autogpt.commands.file_operations import read_file\r\nfrom tests.integration.agent_utils import run_interaction_loop\r\nfrom tests.utils import requires_api_key\r\n\r\n\r\n@requires_api_key(\"OPENAI_API_KEY\")\r\n@pytest.mark.vcr\r\ndef test_browse_website(browser_agent: Agent) -> None:\r\n    file_path = browser_agent.workspace.get_path(\"browse_website.txt\")\r\n    try:\r\n        run_interaction_loop(browser_agent, 120)\r\n    # catch system exit exceptions\r\n    except SystemExit:  # the agent returns an exception when it shuts down\r\n        content = read_file(file_path)\r\n        assert \"£25.89\" in content, f\"Expected £25.89, got {content}\"\r\n"
  },
  {
    "path": "tests/integration/goal_oriented/test_write_file.py",
    "content": "import pytest\n\nfrom autogpt.agent import Agent\nfrom autogpt.commands.file_operations import read_file\nfrom tests.integration.agent_utils import run_interaction_loop\nfrom tests.utils import requires_api_key\n\n\n@requires_api_key(\"OPENAI_API_KEY\")\n@pytest.mark.vcr\ndef test_write_file(writer_agent: Agent) -> None:\n    file_path = str(writer_agent.workspace.get_path(\"hello_world.txt\"))\n    try:\n        run_interaction_loop(writer_agent, 40)\n    # catch system exit exceptions\n    except SystemExit:  # the agent returns an exception when it shuts down\n        content = read_file(file_path)\n        assert content == \"Hello World\", f\"Expected 'Hello World', got {content}\"\n"
  },
  {
    "path": "tests/integration/memory_tests.py",
    "content": "import random\nimport string\nimport sys\nimport unittest\nfrom pathlib import Path\n\nfrom autogpt.config import Config\nfrom autogpt.memory.local import LocalCache\n\n\nclass TestLocalCache(unittest.TestCase):\n    def generate_random_string(self, length):\n        return \"\".join(random.choice(string.ascii_letters) for _ in range(length))\n\n    def setUp(self):\n        \"\"\"Set up the test environment for the LocalCache tests.\"\"\"\n        cfg = cfg = Config()\n        self.cache = LocalCache(cfg)\n        self.cache.clear()\n\n        # Add example texts to the cache\n        self.example_texts = [\n            \"The quick brown fox jumps over the lazy dog\",\n            \"I love machine learning and natural language processing\",\n            \"The cake is a lie, but the pie is always true\",\n            \"ChatGPT is an advanced AI model for conversation\",\n        ]\n        for text in self.example_texts:\n            self.cache.add(text)\n\n        # Add some random strings to test noise\n        for _ in range(5):\n            self.cache.add(self.generate_random_string(10))\n\n    def test_get_relevant(self):\n        \"\"\"Test getting relevant texts from the cache.\"\"\"\n        query = \"I'm interested in artificial intelligence and NLP\"\n        k = 3\n        relevant_texts = self.cache.get_relevant(query, k)\n\n        print(f\"Top {k} relevant texts for the query '{query}':\")\n        for i, text in enumerate(relevant_texts, start=1):\n            print(f\"{i}. {text}\")\n\n        self.assertEqual(len(relevant_texts), k)\n        self.assertIn(self.example_texts[1], relevant_texts)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "tests/integration/milvus_memory_tests.py",
    "content": "# sourcery skip: snake-case-functions\n\"\"\"Tests for the MilvusMemory class.\"\"\"\nimport random\nimport string\nimport unittest\n\nfrom autogpt.config import Config\nfrom autogpt.memory.milvus import MilvusMemory\n\ntry:\n\n    class TestMilvusMemory(unittest.TestCase):\n        \"\"\"Unit tests for the MilvusMemory class.\"\"\"\n\n        def generate_random_string(self, length: int) -> str:\n            return \"\".join(random.choice(string.ascii_letters) for _ in range(length))\n\n        def setUp(self) -> None:\n            cfg = Config()\n            cfg.milvus_addr = \"localhost:19530\"\n            self.memory = MilvusMemory(cfg)\n            self.memory.clear()\n\n            # Add example texts to the cache\n            self.example_texts = [\n                \"The quick brown fox jumps over the lazy dog\",\n                \"I love machine learning and natural language processing\",\n                \"The cake is a lie, but the pie is always true\",\n                \"ChatGPT is an advanced AI model for conversation\",\n            ]\n\n            for text in self.example_texts:\n                self.memory.add(text)\n\n            # Add some random strings to test noise\n            for _ in range(5):\n                self.memory.add(self.generate_random_string(10))\n\n        def test_get_relevant(self) -> None:\n            \"\"\"Test getting relevant texts from the cache.\"\"\"\n            query = \"I'm interested in artificial intelligence and NLP\"\n            num_relevant = 3\n            relevant_texts = self.memory.get_relevant(query, num_relevant)\n\n            print(f\"Top {k} relevant texts for the query '{query}':\")\n            for i, text in enumerate(relevant_texts, start=1):\n                print(f\"{i}. {text}\")\n\n            self.assertEqual(len(relevant_texts), k)\n            self.assertIn(self.example_texts[1], relevant_texts)\n\nexcept:\n    print(\n        \"Skipping tests/integration/milvus_memory_tests.py as Milvus is not installed.\"\n    )\n"
  },
  {
    "path": "tests/integration/test_execute_code.py",
    "content": "import random\nimport string\nimport tempfile\n\nimport pytest\nfrom pytest_mock import MockerFixture\n\nimport autogpt.commands.execute_code as sut  # system under testing\nfrom autogpt.config import Config\n\n\n@pytest.fixture\ndef config_allow_execute(config: Config, mocker: MockerFixture):\n    yield mocker.patch.object(config, \"execute_local_commands\", True)\n\n\n@pytest.fixture\ndef python_test_file(config: Config, random_string):\n    temp_file = tempfile.NamedTemporaryFile(dir=config.workspace_path, suffix=\".py\")\n    temp_file.write(str.encode(f\"print('Hello {random_string}!')\"))\n    temp_file.flush()\n\n    yield temp_file.name\n    temp_file.close()\n\n\n@pytest.fixture\ndef random_string():\n    return \"\".join(random.choice(string.ascii_lowercase) for _ in range(10))\n\n\ndef test_execute_python_file(python_test_file: str, random_string: str):\n    result = sut.execute_python_file(python_test_file)\n    assert result == f\"Hello {random_string}!\\n\"\n\n\ndef test_execute_python_file_invalid():\n    assert all(\n        s in sut.execute_python_file(\"not_python\").lower()\n        for s in [\"error:\", \"invalid\", \".py\"]\n    )\n    assert all(\n        s in sut.execute_python_file(\"notexist.py\").lower()\n        for s in [\"error:\", \"does not exist\"]\n    )\n\n\ndef test_execute_shell(config_allow_execute, random_string):\n    result = sut.execute_shell(f\"echo 'Hello {random_string}!'\")\n    assert f\"Hello {random_string}!\" in result\n"
  },
  {
    "path": "tests/integration/test_git_commands.py",
    "content": "import pytest\nfrom git.exc import GitCommandError\nfrom git.repo.base import Repo\n\nfrom autogpt.commands.git_operations import clone_repository\n\n\n@pytest.fixture\ndef mock_clone_from(mocker):\n    return mocker.patch.object(Repo, \"clone_from\")\n\n\ndef test_clone_auto_gpt_repository(workspace, mock_clone_from, config):\n    mock_clone_from.return_value = None\n\n    repo = \"github.com/Significant-Gravitas/Auto-GPT.git\"\n    scheme = \"https://\"\n    url = scheme + repo\n    clone_path = str(workspace.get_path(\"auto-gpt-repo\"))\n\n    expected_output = f\"Cloned {url} to {clone_path}\"\n\n    clone_result = clone_repository(url=url, clone_path=clone_path)\n\n    assert clone_result == expected_output\n    mock_clone_from.assert_called_once_with(\n        url=f\"{scheme}{config.github_username}:{config.github_api_key}@{repo}\",\n        to_path=clone_path,\n    )\n\n\ndef test_clone_repository_error(workspace, mock_clone_from):\n    url = \"https://github.com/this-repository/does-not-exist.git\"\n    clone_path = str(workspace.get_path(\"does-not-exist\"))\n\n    mock_clone_from.side_effect = GitCommandError(\n        \"clone\", \"fatal: repository not found\", \"\"\n    )\n\n    result = clone_repository(url=url, clone_path=clone_path)\n\n    assert \"Error: \" in result\n"
  },
  {
    "path": "tests/integration/test_llm_utils.py",
    "content": "import string\nfrom unittest.mock import MagicMock\n\nimport pytest\nfrom numpy.random import RandomState\nfrom pytest_mock import MockerFixture\n\nfrom autogpt.config import Config\nfrom autogpt.llm import llm_utils\nfrom autogpt.llm.api_manager import ApiManager\nfrom autogpt.llm.modelsinfo import COSTS\nfrom tests.utils import requires_api_key\n\n\n@pytest.fixture(scope=\"session\")\ndef random_large_string():\n    \"\"\"Big string used to overwhelm token limits.\"\"\"\n    seed = 42\n    n_characters = 30_000\n    random = RandomState(seed)\n    return \"\".join(random.choice(list(string.ascii_lowercase), size=n_characters))\n\n\n@pytest.fixture()\ndef api_manager(mocker: MockerFixture):\n    api_manager = ApiManager()\n    mocker.patch.multiple(\n        api_manager,\n        total_prompt_tokens=0,\n        total_completion_tokens=0,\n        total_cost=0,\n    )\n    yield api_manager\n\n\n@pytest.fixture()\ndef spy_create_embedding(mocker: MockerFixture):\n    return mocker.spy(llm_utils, \"create_embedding\")\n\n\n@pytest.mark.vcr\n@requires_api_key(\"OPENAI_API_KEY\")\ndef test_get_ada_embedding(\n    config: Config, api_manager: ApiManager, spy_create_embedding: MagicMock\n):\n    token_cost = COSTS[config.embedding_model][\"prompt\"]\n    llm_utils.get_ada_embedding(\"test\")\n\n    spy_create_embedding.assert_called_once_with(\"test\", model=config.embedding_model)\n\n    assert (prompt_tokens := api_manager.get_total_prompt_tokens()) == 1\n    assert api_manager.get_total_completion_tokens() == 0\n    assert api_manager.get_total_cost() == (prompt_tokens * token_cost) / 1000\n\n\n@pytest.mark.vcr\n@requires_api_key(\"OPENAI_API_KEY\")\ndef test_get_ada_embedding_large_context(random_large_string):\n    # This test should be able to mock the openai call after we have a fix.  We don't need\n    # to hit the API to test the logic of the function (so not using vcr). This is a quick\n    # regression test to document the issue.\n    llm_utils.get_ada_embedding(random_large_string)\n"
  },
  {
    "path": "tests/integration/test_local_cache.py",
    "content": "# sourcery skip: snake-case-functions\n\"\"\"Tests for LocalCache class\"\"\"\nimport unittest\n\nimport orjson\nimport pytest\n\nfrom autogpt.memory.local import EMBED_DIM, SAVE_OPTIONS\nfrom autogpt.memory.local import LocalCache as LocalCache_\nfrom tests.utils import requires_api_key\n\n\n@pytest.fixture\ndef LocalCache():\n    # Hack, real gross. Singletons are not good times.\n    if LocalCache_ in LocalCache_._instances:\n        del LocalCache_._instances[LocalCache_]\n    return LocalCache_\n\n\n@pytest.fixture\ndef mock_embed_with_ada(mocker):\n    mocker.patch(\n        \"autogpt.memory.local.get_ada_embedding\",\n        return_value=[0.1] * EMBED_DIM,\n    )\n\n\ndef test_init_without_backing_file(LocalCache, config, workspace):\n    cache_file = workspace.root / f\"{config.memory_index}.json\"\n\n    assert not cache_file.exists()\n    LocalCache(config)\n    assert cache_file.exists()\n    assert cache_file.read_text() == \"{}\"\n\n\ndef test_init_with_backing_empty_file(LocalCache, config, workspace):\n    cache_file = workspace.root / f\"{config.memory_index}.json\"\n    cache_file.touch()\n\n    assert cache_file.exists()\n    LocalCache(config)\n    assert cache_file.exists()\n    assert cache_file.read_text() == \"{}\"\n\n\ndef test_init_with_backing_file(LocalCache, config, workspace):\n    cache_file = workspace.root / f\"{config.memory_index}.json\"\n    cache_file.touch()\n\n    raw_data = {\"texts\": [\"test\"]}\n    data = orjson.dumps(raw_data, option=SAVE_OPTIONS)\n    with cache_file.open(\"wb\") as f:\n        f.write(data)\n\n    assert cache_file.exists()\n    LocalCache(config)\n    assert cache_file.exists()\n    assert cache_file.read_text() == \"{}\"\n\n\ndef test_add(LocalCache, config, mock_embed_with_ada):\n    cache = LocalCache(config)\n    cache.add(\"test\")\n    assert cache.data.texts == [\"test\"]\n    assert cache.data.embeddings.shape == (1, EMBED_DIM)\n\n\ndef test_clear(LocalCache, config, mock_embed_with_ada):\n    cache = LocalCache(config)\n    assert cache.data.texts == []\n    assert cache.data.embeddings.shape == (0, EMBED_DIM)\n\n    cache.add(\"test\")\n    assert cache.data.texts == [\"test\"]\n    assert cache.data.embeddings.shape == (1, EMBED_DIM)\n\n    cache.clear()\n    assert cache.data.texts == []\n    assert cache.data.embeddings.shape == (0, EMBED_DIM)\n\n\ndef test_get(LocalCache, config, mock_embed_with_ada):\n    cache = LocalCache(config)\n    assert cache.get(\"test\") == []\n\n    cache.add(\"test\")\n    assert cache.get(\"test\") == [\"test\"]\n\n\n@pytest.mark.vcr\n@requires_api_key(\"OPENAI_API_KEY\")\ndef test_get_relevant(LocalCache, config) -> None:\n    cache = LocalCache(config)\n    text1 = \"Sample text 1\"\n    text2 = \"Sample text 2\"\n    cache.add(text1)\n    cache.add(text2)\n\n    result = cache.get_relevant(text1, 1)\n    assert result == [text1]\n\n\ndef test_get_stats(LocalCache, config, mock_embed_with_ada) -> None:\n    cache = LocalCache(config)\n    text = \"Sample text\"\n    cache.add(text)\n    stats = cache.get_stats()\n    assert stats == (1, cache.data.embeddings.shape)\n"
  },
  {
    "path": "tests/integration/test_memory_management.py",
    "content": "import json\n\nimport pytest\n\nfrom autogpt.config import Config\nfrom autogpt.memory import get_memory\nfrom autogpt.memory_management.store_memory import (\n    save_memory_trimmed_from_context_window,\n)\nfrom tests.utils import requires_api_key\n\n\n@pytest.fixture\ndef message_history_fixture():\n    assistant_reply = {\n        \"thoughts\": {\n            \"text\": \"thoughts\",\n            \"reasoning\": \"reasoning\",\n            \"plan\": \"plan\",\n            \"criticism\": \"criticism\",\n            \"speak\": \"speak\",\n        },\n        \"command\": {\"name\": \"google\", \"args\": {\"query\": \"google_query\"}},\n    }\n    return [\n        {\"content\": json.dumps(assistant_reply, indent=4)},\n        {\"content\": \"Command Result: Important Information.\"},\n    ]\n\n\n@pytest.fixture\ndef expected_permanent_memory() -> str:\n    return \"\"\"Assistant Reply: {\n    \"thoughts\": {\n        \"text\": \"thoughts\",\n        \"reasoning\": \"reasoning\",\n        \"plan\": \"plan\",\n        \"criticism\": \"criticism\",\n        \"speak\": \"speak\"\n    },\n    \"command\": {\n        \"name\": \"google\",\n        \"args\": {\n            \"query\": \"google_query\"\n        }\n    }\n}\nResult: None\nHuman Feedback:Command Result: Important Information.\"\"\"\n\n\n@requires_api_key(\"OPENAI_API_KEY\")\n@pytest.mark.vcr\ndef test_save_memory_trimmed_from_context_window(\n    message_history_fixture, expected_permanent_memory, config: Config\n):\n    next_message_to_add_index = len(message_history_fixture) - 1\n    memory = get_memory(config, init=True)\n    save_memory_trimmed_from_context_window(\n        message_history_fixture, next_message_to_add_index, memory\n    )\n\n    memory_found = memory.get_relevant(\"Important Information\", 5)\n    assert memory_found[0] == expected_permanent_memory\n"
  },
  {
    "path": "tests/integration/test_setup.py",
    "content": "from unittest.mock import patch\n\nimport pytest\n\nfrom autogpt.config.ai_config import AIConfig\nfrom autogpt.setup import (\n    generate_aiconfig_automatic,\n    generate_aiconfig_manual,\n    prompt_user,\n)\nfrom tests.utils import requires_api_key\n\n\n@pytest.mark.vcr\n@requires_api_key(\"OPENAI_API_KEY\")\ndef test_generate_aiconfig_automatic_default():\n    user_inputs = [\"\"]\n    with patch(\"builtins.input\", side_effect=user_inputs):\n        ai_config = prompt_user()\n\n    assert isinstance(ai_config, AIConfig)\n    assert ai_config.ai_name is not None\n    assert ai_config.ai_role is not None\n    assert 1 <= len(ai_config.ai_goals) <= 5\n\n\n@pytest.mark.vcr\n@requires_api_key(\"OPENAI_API_KEY\")\ndef test_generate_aiconfig_automatic_typical():\n    user_prompt = \"Help me create a rock opera about cybernetic giraffes\"\n    ai_config = generate_aiconfig_automatic(user_prompt)\n\n    assert isinstance(ai_config, AIConfig)\n    assert ai_config.ai_name is not None\n    assert ai_config.ai_role is not None\n    assert 1 <= len(ai_config.ai_goals) <= 5\n\n\n@pytest.mark.vcr\n@requires_api_key(\"OPENAI_API_KEY\")\ndef test_generate_aiconfig_automatic_fallback():\n    user_inputs = [\n        \"T&GF£OIBECC()!*\",\n        \"Chef-GPT\",\n        \"an AI designed to browse bake a cake.\",\n        \"Purchase ingredients\",\n        \"Bake a cake\",\n        \"\",\n        \"\",\n    ]\n    with patch(\"builtins.input\", side_effect=user_inputs):\n        ai_config = prompt_user()\n\n    assert isinstance(ai_config, AIConfig)\n    assert ai_config.ai_name == \"Chef-GPT\"\n    assert ai_config.ai_role == \"an AI designed to browse bake a cake.\"\n    assert ai_config.ai_goals == [\"Purchase ingredients\", \"Bake a cake\"]\n\n\n@pytest.mark.vcr\n@requires_api_key(\"OPENAI_API_KEY\")\ndef test_prompt_user_manual_mode():\n    user_inputs = [\n        \"--manual\",\n        \"Chef-GPT\",\n        \"an AI designed to browse bake a cake.\",\n        \"Purchase ingredients\",\n        \"Bake a cake\",\n        \"\",\n        \"\",\n    ]\n    with patch(\"builtins.input\", side_effect=user_inputs):\n        ai_config = prompt_user()\n\n    assert isinstance(ai_config, AIConfig)\n    assert ai_config.ai_name == \"Chef-GPT\"\n    assert ai_config.ai_role == \"an AI designed to browse bake a cake.\"\n    assert ai_config.ai_goals == [\"Purchase ingredients\", \"Bake a cake\"]\n"
  },
  {
    "path": "tests/integration/weaviate_memory_tests.py",
    "content": "import unittest\nfrom uuid import uuid4\n\nfrom weaviate import Client\nfrom weaviate.util import get_valid_uuid\n\nfrom autogpt.config import Config\nfrom autogpt.llm import get_ada_embedding\nfrom autogpt.memory.weaviate import WeaviateMemory\n\n\nclass TestWeaviateMemory(unittest.TestCase):\n    cfg = None\n    client = None\n    index = None\n\n    @classmethod\n    def setUpClass(cls):\n        \"\"\"Set up the test environment for the WeaviateMemory tests.\"\"\"\n        # only create the connection to weaviate once\n        cls.cfg = Config()\n\n        if cls.cfg.use_weaviate_embedded:\n            from weaviate.embedded import EmbeddedOptions\n\n            cls.client = Client(\n                embedded_options=EmbeddedOptions(\n                    hostname=cls.cfg.weaviate_host,\n                    port=int(cls.cfg.weaviate_port),\n                    persistence_data_path=cls.cfg.weaviate_embedded_path,\n                )\n            )\n        else:\n            cls.client = Client(\n                f\"{cls.cfg.weaviate_protocol}://{cls.cfg.weaviate_host}:{self.cfg.weaviate_port}\"\n            )\n\n        cls.index = WeaviateMemory.format_classname(cls.cfg.memory_index)\n\n    \"\"\"\n    In order to run these tests you will need a local instance of\n    Weaviate running. Refer to https://weaviate.io/developers/weaviate/installation/docker-compose\n    for creating local instances using docker.\n    Alternatively in your .env file set the following environmental variables to run Weaviate embedded (see: https://weaviate.io/developers/weaviate/installation/embedded):\n\n        USE_WEAVIATE_EMBEDDED=True\n        WEAVIATE_EMBEDDED_PATH=\"/home/me/.local/share/weaviate\"\n    \"\"\"\n\n    def setUp(self):\n        \"\"\"Set up the test environment for the WeaviateMemory tests.\"\"\"\n        try:\n            self.client.schema.delete_class(self.index)\n        except:\n            pass\n\n        self.memory = WeaviateMemory(self.cfg)\n\n    def test_add(self):\n        \"\"\"Test adding a text to the cache\"\"\"\n        doc = \"You are a Titan name Thanos and you are looking for the Infinity Stones\"\n        self.memory.add(doc)\n        result = self.client.query.get(self.index, [\"raw_text\"]).do()\n        actual = result[\"data\"][\"Get\"][self.index]\n\n        self.assertEqual(len(actual), 1)\n        self.assertEqual(actual[0][\"raw_text\"], doc)\n\n    def test_get(self):\n        \"\"\"Test getting a text from the cache\"\"\"\n        doc = \"You are an Avenger and swore to defend the Galaxy from a menace called Thanos\"\n        # add the document to the cache\n        with self.client.batch as batch:\n            batch.add_data_object(\n                uuid=get_valid_uuid(uuid4()),\n                data_object={\"raw_text\": doc},\n                class_name=self.index,\n                vector=get_ada_embedding(doc),\n            )\n\n            batch.flush()\n\n        actual = self.memory.get(doc)\n\n        self.assertEqual(len(actual), 1)\n        self.assertEqual(actual[0], doc)\n\n    def test_get_stats(self):\n        \"\"\"Test getting the stats of the cache\"\"\"\n        docs = [\n            \"You are now about to count the number of docs in this index\",\n            \"And then you about to find out if you can count correctly\",\n        ]\n\n        [self.memory.add(doc) for doc in docs]\n\n        stats = self.memory.get_stats()\n\n        self.assertTrue(stats)\n        self.assertTrue(\"count\" in stats)\n        self.assertEqual(stats[\"count\"], 2)\n\n    def test_clear(self):\n        \"\"\"Test clearing the cache\"\"\"\n        docs = [\n            \"Shame this is the last test for this class\",\n            \"Testing is fun when someone else is doing it\",\n        ]\n\n        [self.memory.add(doc) for doc in docs]\n\n        self.assertEqual(self.memory.get_stats()[\"count\"], 2)\n\n        self.memory.clear()\n\n        self.assertEqual(self.memory.get_stats()[\"count\"], 0)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "tests/milvus_memory_test.py",
    "content": "# sourcery skip: snake-case-functions\n\"\"\"Tests for the MilvusMemory class.\"\"\"\nimport os\nimport sys\nimport unittest\n\ntry:\n    from autogpt.memory.milvus import MilvusMemory\n\n    def mock_config() -> dict:\n        \"\"\"Mock the config object for testing purposes.\"\"\"\n        # Return a mock config object with the required attributes\n        return type(\n            \"MockConfig\",\n            (object,),\n            {\n                \"debug_mode\": False,\n                \"continuous_mode\": False,\n                \"speak_mode\": False,\n                \"milvus_collection\": \"autogpt\",\n                \"milvus_addr\": \"localhost:19530\",\n            },\n        )\n\n    class TestMilvusMemory(unittest.TestCase):\n        \"\"\"Tests for the MilvusMemory class.\"\"\"\n\n        def setUp(self) -> None:\n            \"\"\"Set up the test environment\"\"\"\n            self.cfg = mock_config()\n            self.memory = MilvusMemory(self.cfg)\n\n        def test_add(self) -> None:\n            \"\"\"Test adding a text to the cache\"\"\"\n            text = \"Sample text\"\n            self.memory.clear()\n            self.memory.add(text)\n            result = self.memory.get(text)\n            self.assertEqual([text], result)\n\n        def test_clear(self) -> None:\n            \"\"\"Test clearing the cache\"\"\"\n            self.memory.clear()\n            self.assertEqual(self.memory.collection.num_entities, 0)\n\n        def test_get(self) -> None:\n            \"\"\"Test getting a text from the cache\"\"\"\n            text = \"Sample text\"\n            self.memory.clear()\n            self.memory.add(text)\n            result = self.memory.get(text)\n            self.assertEqual(result, [text])\n\n        def test_get_relevant(self) -> None:\n            \"\"\"Test getting relevant texts from the cache\"\"\"\n            text1 = \"Sample text 1\"\n            text2 = \"Sample text 2\"\n            self.memory.clear()\n            self.memory.add(text1)\n            self.memory.add(text2)\n            result = self.memory.get_relevant(text1, 1)\n            self.assertEqual(result, [text1])\n\n        def test_get_stats(self) -> None:\n            \"\"\"Test getting the cache stats\"\"\"\n            text = \"Sample text\"\n            self.memory.clear()\n            self.memory.add(text)\n            stats = self.memory.get_stats()\n            self.assertEqual(15, len(stats))\n\nexcept ImportError as err:\n    print(f\"Skipping tests for MilvusMemory: {err}\")\n"
  },
  {
    "path": "tests/mocks/__init__.py",
    "content": ""
  },
  {
    "path": "tests/mocks/mock_commands.py",
    "content": "from autogpt.commands.command import command\n\n\n@command(\"function_based\", \"Function-based test command\")\ndef function_based(arg1: int, arg2: str) -> str:\n    \"\"\"A function-based test command that returns a string with the two arguments separated by a dash.\"\"\"\n    return f\"{arg1} - {arg2}\"\n"
  },
  {
    "path": "tests/test_agent.py",
    "content": "from unittest.mock import MagicMock\n\nimport pytest\n\nfrom autogpt.agent import Agent\nfrom autogpt.config import Config\n\n\n@pytest.fixture\ndef agent():\n    ai_name = \"Test AI\"\n    memory = MagicMock()\n    full_message_history = []\n    next_action_count = 0\n    command_registry = MagicMock()\n    config = Config()\n    system_prompt = \"System prompt\"\n    triggering_prompt = \"Triggering prompt\"\n    workspace_directory = \"workspace_directory\"\n\n    agent = Agent(\n        ai_name,\n        memory,\n        full_message_history,\n        next_action_count,\n        command_registry,\n        config,\n        system_prompt,\n        triggering_prompt,\n        workspace_directory,\n    )\n    return agent\n\n\ndef test_agent_initialization(agent):\n    assert agent.ai_name == \"Test AI\"\n    assert agent.memory == agent.memory\n    assert agent.full_message_history == []\n    assert agent.next_action_count == 0\n    assert agent.command_registry == agent.command_registry\n    assert agent.config == agent.config\n    assert agent.system_prompt == \"System prompt\"\n    assert agent.triggering_prompt == \"Triggering prompt\"\n\n\n# More test methods can be added for specific agent interactions\n# For example, mocking chat_with_ai and testing the agent's interaction loop\n"
  },
  {
    "path": "tests/test_agent_manager.py",
    "content": "import pytest\n\nfrom autogpt.agent.agent_manager import AgentManager\nfrom autogpt.llm import create_chat_completion\n\n\n@pytest.fixture\ndef agent_manager():\n    # Hack, real gross. Singletons are not good times.\n    if AgentManager in AgentManager._instances:\n        del AgentManager._instances[AgentManager]\n    return AgentManager()\n\n\n@pytest.fixture\ndef task():\n    return \"translate English to French\"\n\n\n@pytest.fixture\ndef prompt():\n    return \"Translate the following English text to French: 'Hello, how are you?'\"\n\n\n@pytest.fixture\ndef model():\n    return \"gpt-3.5-turbo\"\n\n\n@pytest.fixture(autouse=True)\ndef mock_create_chat_completion(mocker):\n    mock_create_chat_completion = mocker.patch(\n        \"autogpt.agent.agent_manager.create_chat_completion\",\n        wraps=create_chat_completion,\n    )\n    mock_create_chat_completion.return_value = \"irrelevant\"\n    return mock_create_chat_completion\n\n\ndef test_create_agent(agent_manager, task, prompt, model):\n    key, agent_reply = agent_manager.create_agent(task, prompt, model)\n    assert isinstance(key, int)\n    assert isinstance(agent_reply, str)\n    assert key in agent_manager.agents\n\n\ndef test_message_agent(agent_manager, task, prompt, model):\n    key, _ = agent_manager.create_agent(task, prompt, model)\n    user_message = \"Please translate 'Good morning' to French.\"\n    agent_reply = agent_manager.message_agent(key, user_message)\n    assert isinstance(agent_reply, str)\n\n\ndef test_list_agents(agent_manager, task, prompt, model):\n    key, _ = agent_manager.create_agent(task, prompt, model)\n    agents_list = agent_manager.list_agents()\n    assert isinstance(agents_list, list)\n    assert (key, task) in agents_list\n\n\ndef test_delete_agent(agent_manager, task, prompt, model):\n    key, _ = agent_manager.create_agent(task, prompt, model)\n    success = agent_manager.delete_agent(key)\n    assert success\n    assert key not in agent_manager.agents\n"
  },
  {
    "path": "tests/test_ai_config.py",
    "content": "from autogpt.config.ai_config import AIConfig\n\n\"\"\"\nTest cases for the AIConfig class, which handles loads the AI configuration\nsettings from a YAML file.\n\"\"\"\n\n\ndef test_goals_are_always_lists_of_strings(tmp_path):\n    \"\"\"Test if the goals attribute is always a list of strings.\"\"\"\n\n    yaml_content = \"\"\"\nai_goals:\n- Goal 1: Make a sandwich\n- Goal 2, Eat the sandwich\n- Goal 3 - Go to sleep\n- \"Goal 4: Wake up\"\nai_name: McFamished\nai_role: A hungry AI\napi_budget: 0.0\n\"\"\"\n    config_file = tmp_path / \"ai_settings.yaml\"\n    config_file.write_text(yaml_content)\n\n    ai_config = AIConfig.load(config_file)\n\n    assert len(ai_config.ai_goals) == 4\n    assert ai_config.ai_goals[0] == \"Goal 1: Make a sandwich\"\n    assert ai_config.ai_goals[1] == \"Goal 2, Eat the sandwich\"\n    assert ai_config.ai_goals[2] == \"Goal 3 - Go to sleep\"\n    assert ai_config.ai_goals[3] == \"Goal 4: Wake up\"\n\n    config_file.write_text(\"\")\n    ai_config.save(config_file)\n\n    yaml_content2 = \"\"\"ai_goals:\n- 'Goal 1: Make a sandwich'\n- Goal 2, Eat the sandwich\n- Goal 3 - Go to sleep\n- 'Goal 4: Wake up'\nai_name: McFamished\nai_role: A hungry AI\napi_budget: 0.0\n\"\"\"\n    assert config_file.read_text() == yaml_content2\n"
  },
  {
    "path": "tests/test_api_manager.py",
    "content": "from unittest.mock import MagicMock, patch\n\nimport pytest\n\nfrom autogpt.llm import COSTS, ApiManager\n\napi_manager = ApiManager()\n\n\n@pytest.fixture(autouse=True)\ndef reset_api_manager():\n    api_manager.reset()\n    yield\n\n\n@pytest.fixture(autouse=True)\ndef mock_costs():\n    with patch.dict(\n        COSTS,\n        {\n            \"gpt-3.5-turbo\": {\"prompt\": 0.002, \"completion\": 0.002},\n            \"text-embedding-ada-002\": {\"prompt\": 0.0004, \"completion\": 0},\n        },\n        clear=True,\n    ):\n        yield\n\n\nclass TestApiManager:\n    @staticmethod\n    def test_create_chat_completion_debug_mode(caplog):\n        \"\"\"Test if debug mode logs response.\"\"\"\n        api_manager_debug = ApiManager(debug=True)\n        messages = [\n            {\"role\": \"system\", \"content\": \"You are a helpful assistant.\"},\n            {\"role\": \"user\", \"content\": \"Who won the world series in 2020?\"},\n        ]\n        model = \"gpt-3.5-turbo\"\n\n        with patch(\"openai.ChatCompletion.create\") as mock_create:\n            mock_response = MagicMock()\n            mock_response.usage.prompt_tokens = 10\n            mock_response.usage.completion_tokens = 20\n            mock_create.return_value = mock_response\n\n            api_manager_debug.create_chat_completion(messages, model=model)\n\n            assert \"Response\" in caplog.text\n\n    @staticmethod\n    def test_create_chat_completion_empty_messages():\n        \"\"\"Test if empty messages result in zero tokens and cost.\"\"\"\n        messages = []\n        model = \"gpt-3.5-turbo\"\n\n        with patch(\"openai.ChatCompletion.create\") as mock_create:\n            mock_response = MagicMock()\n            mock_response.usage.prompt_tokens = 0\n            mock_response.usage.completion_tokens = 0\n            mock_create.return_value = mock_response\n\n            api_manager.create_chat_completion(messages, model=model)\n\n            assert api_manager.get_total_prompt_tokens() == 0\n            assert api_manager.get_total_completion_tokens() == 0\n            assert api_manager.get_total_cost() == 0\n\n    @staticmethod\n    def test_create_chat_completion_valid_inputs():\n        \"\"\"Test if valid inputs result in correct tokens and cost.\"\"\"\n        messages = [\n            {\"role\": \"system\", \"content\": \"You are a helpful assistant.\"},\n            {\"role\": \"user\", \"content\": \"Who won the world series in 2020?\"},\n        ]\n        model = \"gpt-3.5-turbo\"\n\n        with patch(\"openai.ChatCompletion.create\") as mock_create:\n            mock_response = MagicMock()\n            mock_response.usage.prompt_tokens = 10\n            mock_response.usage.completion_tokens = 20\n            mock_create.return_value = mock_response\n\n            api_manager.create_chat_completion(messages, model=model)\n\n            assert api_manager.get_total_prompt_tokens() == 10\n            assert api_manager.get_total_completion_tokens() == 20\n            assert api_manager.get_total_cost() == (10 * 0.002 + 20 * 0.002) / 1000\n\n    def test_getter_methods(self):\n        \"\"\"Test the getter methods for total tokens, cost, and budget.\"\"\"\n        api_manager.update_cost(60, 120, \"gpt-3.5-turbo\")\n        api_manager.set_total_budget(10.0)\n        assert api_manager.get_total_prompt_tokens() == 60\n        assert api_manager.get_total_completion_tokens() == 120\n        assert api_manager.get_total_cost() == (60 * 0.002 + 120 * 0.002) / 1000\n        assert api_manager.get_total_budget() == 10.0\n\n    @staticmethod\n    def test_set_total_budget():\n        \"\"\"Test if setting the total budget works correctly.\"\"\"\n        total_budget = 10.0\n        api_manager.set_total_budget(total_budget)\n\n        assert api_manager.get_total_budget() == total_budget\n\n    @staticmethod\n    def test_update_cost():\n        \"\"\"Test if updating the cost works correctly.\"\"\"\n        prompt_tokens = 50\n        completion_tokens = 100\n        model = \"gpt-3.5-turbo\"\n\n        api_manager.update_cost(prompt_tokens, completion_tokens, model)\n\n        assert api_manager.get_total_prompt_tokens() == 50\n        assert api_manager.get_total_completion_tokens() == 100\n        assert api_manager.get_total_cost() == (50 * 0.002 + 100 * 0.002) / 1000\n"
  },
  {
    "path": "tests/test_commands.py",
    "content": "import os\nimport shutil\nimport sys\nfrom pathlib import Path\n\nimport pytest\n\nfrom autogpt.commands.command import Command, CommandRegistry\n\n\nclass TestCommand:\n    \"\"\"Test cases for the Command class.\"\"\"\n\n    @staticmethod\n    def example_command_method(arg1: int, arg2: str) -> str:\n        \"\"\"Example function for testing the Command class.\"\"\"\n        # This function is static because it is not used by any other test cases.\n        return f\"{arg1} - {arg2}\"\n\n    def test_command_creation(self):\n        \"\"\"Test that a Command object can be created with the correct attributes.\"\"\"\n        cmd = Command(\n            name=\"example\",\n            description=\"Example command\",\n            method=self.example_command_method,\n        )\n\n        assert cmd.name == \"example\"\n        assert cmd.description == \"Example command\"\n        assert cmd.method == self.example_command_method\n        assert cmd.signature == \"(arg1: int, arg2: str) -> str\"\n\n    def test_command_call(self):\n        \"\"\"Test that Command(*args) calls and returns the result of method(*args).\"\"\"\n        # Create a Command object with the example_command_method.\n        cmd = Command(\n            name=\"example\",\n            description=\"Example command\",\n            method=self.example_command_method,\n        )\n        result = cmd(arg1=1, arg2=\"test\")\n        assert result == \"1 - test\"\n\n    def test_command_call_with_invalid_arguments(self):\n        \"\"\"Test that calling a Command object with invalid arguments raises a TypeError.\"\"\"\n        cmd = Command(\n            name=\"example\",\n            description=\"Example command\",\n            method=self.example_command_method,\n        )\n        with pytest.raises(TypeError):\n            cmd(arg1=\"invalid\", does_not_exist=\"test\")\n\n    def test_command_default_signature(self):\n        \"\"\"Test that the default signature is generated correctly.\"\"\"\n        cmd = Command(\n            name=\"example\",\n            description=\"Example command\",\n            method=self.example_command_method,\n        )\n        assert cmd.signature == \"(arg1: int, arg2: str) -> str\"\n\n    def test_command_custom_signature(self):\n        custom_signature = \"custom_arg1: int, custom_arg2: str\"\n        cmd = Command(\n            name=\"example\",\n            description=\"Example command\",\n            method=self.example_command_method,\n            signature=custom_signature,\n        )\n\n        assert cmd.signature == custom_signature\n\n\nclass TestCommandRegistry:\n    @staticmethod\n    def example_command_method(arg1: int, arg2: str) -> str:\n        return f\"{arg1} - {arg2}\"\n\n    def test_register_command(self):\n        \"\"\"Test that a command can be registered to the registry.\"\"\"\n        registry = CommandRegistry()\n        cmd = Command(\n            name=\"example\",\n            description=\"Example command\",\n            method=self.example_command_method,\n        )\n\n        registry.register(cmd)\n\n        assert cmd.name in registry.commands\n        assert registry.commands[cmd.name] == cmd\n\n    def test_unregister_command(self):\n        \"\"\"Test that a command can be unregistered from the registry.\"\"\"\n        registry = CommandRegistry()\n        cmd = Command(\n            name=\"example\",\n            description=\"Example command\",\n            method=self.example_command_method,\n        )\n\n        registry.register(cmd)\n        registry.unregister(cmd.name)\n\n        assert cmd.name not in registry.commands\n\n    def test_get_command(self):\n        \"\"\"Test that a command can be retrieved from the registry.\"\"\"\n        registry = CommandRegistry()\n        cmd = Command(\n            name=\"example\",\n            description=\"Example command\",\n            method=self.example_command_method,\n        )\n\n        registry.register(cmd)\n        retrieved_cmd = registry.get_command(cmd.name)\n\n        assert retrieved_cmd == cmd\n\n    def test_get_nonexistent_command(self):\n        \"\"\"Test that attempting to get a nonexistent command raises a KeyError.\"\"\"\n        registry = CommandRegistry()\n\n        with pytest.raises(KeyError):\n            registry.get_command(\"nonexistent_command\")\n\n    def test_call_command(self):\n        \"\"\"Test that a command can be called through the registry.\"\"\"\n        registry = CommandRegistry()\n        cmd = Command(\n            name=\"example\",\n            description=\"Example command\",\n            method=self.example_command_method,\n        )\n\n        registry.register(cmd)\n        result = registry.call(\"example\", arg1=1, arg2=\"test\")\n\n        assert result == \"1 - test\"\n\n    def test_call_nonexistent_command(self):\n        \"\"\"Test that attempting to call a nonexistent command raises a KeyError.\"\"\"\n        registry = CommandRegistry()\n\n        with pytest.raises(KeyError):\n            registry.call(\"nonexistent_command\", arg1=1, arg2=\"test\")\n\n    def test_get_command_prompt(self):\n        \"\"\"Test that the command prompt is correctly formatted.\"\"\"\n        registry = CommandRegistry()\n        cmd = Command(\n            name=\"example\",\n            description=\"Example command\",\n            method=self.example_command_method,\n        )\n\n        registry.register(cmd)\n        command_prompt = registry.command_prompt()\n\n        assert f\"(arg1: int, arg2: str)\" in command_prompt\n\n    def test_import_mock_commands_module(self):\n        \"\"\"Test that the registry can import a module with mock command plugins.\"\"\"\n        registry = CommandRegistry()\n        mock_commands_module = \"tests.mocks.mock_commands\"\n\n        registry.import_commands(mock_commands_module)\n\n        assert \"function_based\" in registry.commands\n        assert registry.commands[\"function_based\"].name == \"function_based\"\n        assert (\n            registry.commands[\"function_based\"].description\n            == \"Function-based test command\"\n        )\n\n    def test_import_temp_command_file_module(self, tmp_path):\n        \"\"\"\n        Test that the registry can import a command plugins module from a temp file.\n        Args:\n            tmp_path (pathlib.Path): Path to a temporary directory.\n        \"\"\"\n        registry = CommandRegistry()\n\n        # Create a temp command file\n        src = Path(os.getcwd()) / \"tests/mocks/mock_commands.py\"\n        temp_commands_file = tmp_path / \"mock_commands.py\"\n        shutil.copyfile(src, temp_commands_file)\n\n        # Add the temp directory to sys.path to make the module importable\n        sys.path.append(str(tmp_path))\n\n        temp_commands_module = \"mock_commands\"\n        registry.import_commands(temp_commands_module)\n\n        # Remove the temp directory from sys.path\n        sys.path.remove(str(tmp_path))\n\n        assert \"function_based\" in registry.commands\n        assert registry.commands[\"function_based\"].name == \"function_based\"\n        assert (\n            registry.commands[\"function_based\"].description\n            == \"Function-based test command\"\n        )\n"
  },
  {
    "path": "tests/test_config.py",
    "content": "\"\"\"\nTest cases for the Config class, which handles the configuration settings\nfor the AI and ensures it behaves as a singleton.\n\"\"\"\n\nimport pytest\n\nfrom autogpt.config import Config\n\n\ndef test_initial_values(config):\n    \"\"\"\n    Test if the initial values of the Config class attributes are set correctly.\n    \"\"\"\n    assert config.debug_mode == False\n    assert config.continuous_mode == False\n    assert config.speak_mode == False\n    assert config.fast_llm_model == \"gpt-3.5-turbo\"\n    assert config.smart_llm_model == \"gpt-4\"\n    assert config.fast_token_limit == 4000\n    assert config.smart_token_limit == 8000\n\n\ndef test_set_continuous_mode(config):\n    \"\"\"\n    Test if the set_continuous_mode() method updates the continuous_mode attribute.\n    \"\"\"\n    # Store continuous mode to reset it after the test\n    continuous_mode = config.continuous_mode\n\n    config.set_continuous_mode(True)\n    assert config.continuous_mode == True\n\n    # Reset continuous mode\n    config.set_continuous_mode(continuous_mode)\n\n\ndef test_set_speak_mode(config):\n    \"\"\"\n    Test if the set_speak_mode() method updates the speak_mode attribute.\n    \"\"\"\n    # Store speak mode to reset it after the test\n    speak_mode = config.speak_mode\n\n    config.set_speak_mode(True)\n    assert config.speak_mode == True\n\n    # Reset speak mode\n    config.set_speak_mode(speak_mode)\n\n\ndef test_set_fast_llm_model(config):\n    \"\"\"\n    Test if the set_fast_llm_model() method updates the fast_llm_model attribute.\n    \"\"\"\n    # Store model name to reset it after the test\n    fast_llm_model = config.fast_llm_model\n\n    config.set_fast_llm_model(\"gpt-3.5-turbo-test\")\n    assert config.fast_llm_model == \"gpt-3.5-turbo-test\"\n\n    # Reset model name\n    config.set_fast_llm_model(fast_llm_model)\n\n\ndef test_set_smart_llm_model(config):\n    \"\"\"\n    Test if the set_smart_llm_model() method updates the smart_llm_model attribute.\n    \"\"\"\n    # Store model name to reset it after the test\n    smart_llm_model = config.smart_llm_model\n\n    config.set_smart_llm_model(\"gpt-4-test\")\n    assert config.smart_llm_model == \"gpt-4-test\"\n\n    # Reset model name\n    config.set_smart_llm_model(smart_llm_model)\n\n\ndef test_set_fast_token_limit(config):\n    \"\"\"\n    Test if the set_fast_token_limit() method updates the fast_token_limit attribute.\n    \"\"\"\n    # Store token limit to reset it after the test\n    fast_token_limit = config.fast_token_limit\n\n    config.set_fast_token_limit(5000)\n    assert config.fast_token_limit == 5000\n\n    # Reset token limit\n    config.set_fast_token_limit(fast_token_limit)\n\n\ndef test_set_smart_token_limit(config):\n    \"\"\"\n    Test if the set_smart_token_limit() method updates the smart_token_limit attribute.\n    \"\"\"\n    # Store token limit to reset it after the test\n    smart_token_limit = config.smart_token_limit\n\n    config.set_smart_token_limit(9000)\n    assert config.smart_token_limit == 9000\n\n    # Reset token limit\n    config.set_smart_token_limit(smart_token_limit)\n\n\ndef test_set_debug_mode(config):\n    \"\"\"\n    Test if the set_debug_mode() method updates the debug_mode attribute.\n    \"\"\"\n    # Store debug mode to reset it after the test\n    debug_mode = config.debug_mode\n\n    config.set_debug_mode(True)\n    assert config.debug_mode == True\n\n    # Reset debug mode\n    config.set_debug_mode(debug_mode)\n"
  },
  {
    "path": "tests/test_image_gen.py",
    "content": "import functools\nimport hashlib\nfrom pathlib import Path\n\nimport pytest\nfrom PIL import Image\n\nfrom autogpt.commands.image_gen import generate_image, generate_image_with_sd_webui\nfrom tests.utils import requires_api_key\n\n\n@pytest.fixture(params=[256, 512, 1024])\ndef image_size(request):\n    \"\"\"Parametrize image size.\"\"\"\n    return request.param\n\n\n@pytest.mark.xfail(\n    reason=\"The image is too big to be put in a cassette for a CI pipeline. We're looking into a solution.\"\n)\n@requires_api_key(\"OPENAI_API_KEY\")\ndef test_dalle(config, workspace, image_size):\n    \"\"\"Test DALL-E image generation.\"\"\"\n    generate_and_validate(\n        config,\n        workspace,\n        image_provider=\"dalle\",\n        image_size=image_size,\n    )\n\n\n@pytest.mark.xfail(\n    reason=\"The image is too big to be put in a cassette for a CI pipeline. We're looking into a solution.\"\n)\n@requires_api_key(\"HUGGINGFACE_API_TOKEN\")\n@pytest.mark.parametrize(\n    \"image_model\",\n    [\"CompVis/stable-diffusion-v1-4\", \"stabilityai/stable-diffusion-2-1\"],\n)\ndef test_huggingface(config, workspace, image_size, image_model):\n    \"\"\"Test HuggingFace image generation.\"\"\"\n    generate_and_validate(\n        config,\n        workspace,\n        image_provider=\"huggingface\",\n        image_size=image_size,\n        hugging_face_image_model=image_model,\n    )\n\n\n@pytest.mark.xfail(reason=\"SD WebUI call does not work.\")\ndef test_sd_webui(config, workspace, image_size):\n    \"\"\"Test SD WebUI image generation.\"\"\"\n    generate_and_validate(\n        config,\n        workspace,\n        image_provider=\"sd_webui\",\n        image_size=image_size,\n    )\n\n\n@pytest.mark.xfail(reason=\"SD WebUI call does not work.\")\ndef test_sd_webui_negative_prompt(config, workspace, image_size):\n    gen_image = functools.partial(\n        generate_image_with_sd_webui,\n        prompt=\"astronaut riding a horse\",\n        size=image_size,\n        extra={\"seed\": 123},\n    )\n\n    # Generate an image with a negative prompt\n    image_path = lst(gen_image(negative_prompt=\"horse\", filename=\"negative.jpg\"))\n    with Image.open(image_path) as img:\n        neg_image_hash = hashlib.md5(img.tobytes()).hexdigest()\n\n    # Generate an image without a negative prompt\n    image_path = lst(gen_image(filename=\"positive.jpg\"))\n    with Image.open(image_path) as img:\n        image_hash = hashlib.md5(img.tobytes()).hexdigest()\n\n    assert image_hash != neg_image_hash\n\n\ndef lst(txt):\n    \"\"\"Extract the file path from the output of `generate_image()`\"\"\"\n    return Path(txt.split(\":\")[1].strip())\n\n\ndef generate_and_validate(\n    config,\n    workspace,\n    image_size,\n    image_provider,\n    hugging_face_image_model=None,\n    **kwargs,\n):\n    \"\"\"Generate an image and validate the output.\"\"\"\n    config.image_provider = image_provider\n    config.huggingface_image_model = hugging_face_image_model\n    prompt = \"astronaut riding a horse\"\n\n    image_path = lst(generate_image(prompt, image_size, **kwargs))\n    assert image_path.exists()\n    with Image.open(image_path) as img:\n        assert img.size == (image_size, image_size)\n"
  },
  {
    "path": "tests/test_logs.py",
    "content": "import pytest\n\nfrom autogpt.logs import remove_color_codes\n\n\n@pytest.mark.parametrize(\n    \"raw_text, clean_text\",\n    [\n        (\n            \"COMMAND = \\x1b[36mbrowse_website\\x1b[0m  ARGUMENTS = \\x1b[36m{'url': 'https://www.google.com', 'question': 'What is the capital of France?'}\\x1b[0m\",\n            \"COMMAND = browse_website  ARGUMENTS = {'url': 'https://www.google.com', 'question': 'What is the capital of France?'}\",\n        ),\n        (\n            \"{'Schaue dir meine Projekte auf github () an, als auch meine Webseiten': 'https://github.com/Significant-Gravitas/Auto-GPT, https://discord.gg/autogpt und https://twitter.com/SigGravitas'}\",\n            \"{'Schaue dir meine Projekte auf github () an, als auch meine Webseiten': 'https://github.com/Significant-Gravitas/Auto-GPT, https://discord.gg/autogpt und https://twitter.com/SigGravitas'}\",\n        ),\n        (\"\", \"\"),\n        (\"hello\", \"hello\"),\n        (\"hello\\x1B[31m world\", \"hello world\"),\n        (\"\\x1B[36mHello,\\x1B[32m World!\", \"Hello, World!\"),\n        (\n            \"\\x1B[1m\\x1B[31mError:\\x1B[0m\\x1B[31m file not found\",\n            \"Error: file not found\",\n        ),\n    ],\n)\ndef test_remove_color_codes(raw_text, clean_text):\n    assert remove_color_codes(raw_text) == clean_text\n"
  },
  {
    "path": "tests/test_prompt_generator.py",
    "content": "from unittest import TestCase\n\nfrom autogpt.prompts.generator import PromptGenerator\n\n\nclass TestPromptGenerator(TestCase):\n    \"\"\"\n    Test cases for the PromptGenerator class, which is responsible for generating\n    prompts for the AI with constraints, commands, resources, and performance evaluations.\n    \"\"\"\n\n    @classmethod\n    def setUpClass(cls):\n        \"\"\"\n        Set up the initial state for each test method by creating an instance of PromptGenerator.\n        \"\"\"\n        cls.generator = PromptGenerator()\n\n    # Test whether the add_constraint() method adds a constraint to the generator's constraints list\n    def test_add_constraint(self):\n        \"\"\"\n        Test if the add_constraint() method adds a constraint to the generator's constraints list.\n        \"\"\"\n        constraint = \"Constraint1\"\n        self.generator.add_constraint(constraint)\n        self.assertIn(constraint, self.generator.constraints)\n\n    # Test whether the add_command() method adds a command to the generator's commands list\n    def test_add_command(self):\n        \"\"\"\n        Test if the add_command() method adds a command to the generator's commands list.\n        \"\"\"\n        command_label = \"Command Label\"\n        command_name = \"command_name\"\n        args = {\"arg1\": \"value1\", \"arg2\": \"value2\"}\n        self.generator.add_command(command_label, command_name, args)\n        command = {\n            \"label\": command_label,\n            \"name\": command_name,\n            \"args\": args,\n            \"function\": None,\n        }\n        self.assertIn(command, self.generator.commands)\n\n    def test_add_resource(self):\n        \"\"\"\n        Test if the add_resource() method adds a resource to the generator's resources list.\n        \"\"\"\n        resource = \"Resource1\"\n        self.generator.add_resource(resource)\n        self.assertIn(resource, self.generator.resources)\n\n    def test_add_performance_evaluation(self):\n        \"\"\"\n        Test if the add_performance_evaluation() method adds an evaluation to the generator's\n        performance_evaluation list.\n        \"\"\"\n        evaluation = \"Evaluation1\"\n        self.generator.add_performance_evaluation(evaluation)\n        self.assertIn(evaluation, self.generator.performance_evaluation)\n\n    def test_generate_prompt_string(self):\n        \"\"\"\n        Test if the generate_prompt_string() method generates a prompt string with all the added\n        constraints, commands, resources, and evaluations.\n        \"\"\"\n        # Define the test data\n        constraints = [\"Constraint1\", \"Constraint2\"]\n        commands = [\n            {\n                \"label\": \"Command1\",\n                \"name\": \"command_name1\",\n                \"args\": {\"arg1\": \"value1\"},\n            },\n            {\n                \"label\": \"Command2\",\n                \"name\": \"command_name2\",\n                \"args\": {},\n            },\n        ]\n        resources = [\"Resource1\", \"Resource2\"]\n        evaluations = [\"Evaluation1\", \"Evaluation2\"]\n\n        # Add test data to the generator\n        for constraint in constraints:\n            self.generator.add_constraint(constraint)\n        for command in commands:\n            self.generator.add_command(\n                command[\"label\"], command[\"name\"], command[\"args\"]\n            )\n        for resource in resources:\n            self.generator.add_resource(resource)\n        for evaluation in evaluations:\n            self.generator.add_performance_evaluation(evaluation)\n\n        # Generate the prompt string and verify its correctness\n        prompt_string = self.generator.generate_prompt_string()\n        self.assertIsNotNone(prompt_string)\n\n        # Check if all constraints, commands, resources, and evaluations are present in the prompt string\n        for constraint in constraints:\n            self.assertIn(constraint, prompt_string)\n        for command in commands:\n            self.assertIn(command[\"name\"], prompt_string)\n            for key, value in command[\"args\"].items():\n                self.assertIn(f'\"{key}\": \"{value}\"', prompt_string)\n        for resource in resources:\n            self.assertIn(resource, prompt_string)\n        for evaluation in evaluations:\n            self.assertIn(evaluation, prompt_string)\n\n        self.assertIn(\"constraints\", prompt_string.lower())\n        self.assertIn(\"commands\", prompt_string.lower())\n        self.assertIn(\"resources\", prompt_string.lower())\n        self.assertIn(\"performance evaluation\", prompt_string.lower())\n"
  },
  {
    "path": "tests/test_token_counter.py",
    "content": "import pytest\n\nfrom autogpt.llm import count_message_tokens, count_string_tokens\n\n\ndef test_count_message_tokens():\n    messages = [\n        {\"role\": \"user\", \"content\": \"Hello\"},\n        {\"role\": \"assistant\", \"content\": \"Hi there!\"},\n    ]\n    assert count_message_tokens(messages) == 17\n\n\ndef test_count_message_tokens_with_name():\n    messages = [\n        {\"role\": \"user\", \"content\": \"Hello\", \"name\": \"John\"},\n        {\"role\": \"assistant\", \"content\": \"Hi there!\"},\n    ]\n    assert count_message_tokens(messages) == 17\n\n\ndef test_count_message_tokens_empty_input():\n    \"\"\"Empty input should return 3 tokens\"\"\"\n    assert count_message_tokens([]) == 3\n\n\ndef test_count_message_tokens_invalid_model():\n    \"\"\"Invalid model should raise a KeyError\"\"\"\n    messages = [\n        {\"role\": \"user\", \"content\": \"Hello\"},\n        {\"role\": \"assistant\", \"content\": \"Hi there!\"},\n    ]\n    with pytest.raises(KeyError):\n        count_message_tokens(messages, model=\"invalid_model\")\n\n\ndef test_count_message_tokens_gpt_4():\n    messages = [\n        {\"role\": \"user\", \"content\": \"Hello\"},\n        {\"role\": \"assistant\", \"content\": \"Hi there!\"},\n    ]\n    assert count_message_tokens(messages, model=\"gpt-4-0314\") == 15\n\n\ndef test_count_string_tokens():\n    \"\"\"Test that the string tokens are counted correctly.\"\"\"\n\n    string = \"Hello, world!\"\n    assert count_string_tokens(string, model_name=\"gpt-3.5-turbo-0301\") == 4\n\n\ndef test_count_string_tokens_empty_input():\n    \"\"\"Test that the string tokens are counted correctly.\"\"\"\n\n    assert count_string_tokens(\"\", model_name=\"gpt-3.5-turbo-0301\") == 0\n\n\ndef test_count_message_tokens_invalid_model():\n    \"\"\"Invalid model should raise a NotImplementedError\"\"\"\n    messages = [\n        {\"role\": \"user\", \"content\": \"Hello\"},\n        {\"role\": \"assistant\", \"content\": \"Hi there!\"},\n    ]\n    with pytest.raises(NotImplementedError):\n        count_message_tokens(messages, model=\"invalid_model\")\n\n\ndef test_count_string_tokens_gpt_4():\n    \"\"\"Test that the string tokens are counted correctly.\"\"\"\n\n    string = \"Hello, world!\"\n    assert count_string_tokens(string, model_name=\"gpt-4-0314\") == 4\n"
  },
  {
    "path": "tests/test_utils.py",
    "content": "import os\nfrom unittest.mock import Mock, patch\n\nimport pytest\nimport requests\nfrom colorama import Fore\nfrom git import Repo\n\nfrom autogpt.utils import (\n    clean_input,\n    get_bulletin_from_web,\n    get_current_git_branch,\n    get_latest_bulletin,\n    readable_file_size,\n    validate_yaml_file,\n)\nfrom tests.utils import skip_in_ci\n\n\ndef test_validate_yaml_file_valid():\n    with open(\"valid_test_file.yaml\", \"w\") as f:\n        f.write(\"setting: value\")\n    result, message = validate_yaml_file(\"valid_test_file.yaml\")\n    os.remove(\"valid_test_file.yaml\")\n\n    assert result == True\n    assert \"Successfully validated\" in message\n\n\ndef test_validate_yaml_file_not_found():\n    result, message = validate_yaml_file(\"non_existent_file.yaml\")\n\n    assert result == False\n    assert \"wasn't found\" in message\n\n\ndef test_validate_yaml_file_invalid():\n    with open(\"invalid_test_file.yaml\", \"w\") as f:\n        f.write(\n            \"settings:\\n  first_setting: value\\n  second_setting: value\\n    nested_setting: value\\n  third_setting: value\\nunindented_setting: value\"\n        )\n    result, message = validate_yaml_file(\"invalid_test_file.yaml\")\n    os.remove(\"invalid_test_file.yaml\")\n    print(result)\n    print(message)\n    assert result == False\n    assert \"There was an issue while trying to read\" in message\n\n\ndef test_readable_file_size():\n    size_in_bytes = 1024 * 1024 * 3.5  # 3.5 MB\n    readable_size = readable_file_size(size_in_bytes)\n\n    assert readable_size == \"3.50 MB\"\n\n\n@patch(\"requests.get\")\ndef test_get_bulletin_from_web_success(mock_get):\n    expected_content = \"Test bulletin from web\"\n\n    mock_get.return_value.status_code = 200\n    mock_get.return_value.text = expected_content\n    bulletin = get_bulletin_from_web()\n\n    assert expected_content in bulletin\n    mock_get.assert_called_with(\n        \"https://raw.githubusercontent.com/Significant-Gravitas/Auto-GPT/master/BULLETIN.md\"\n    )\n\n\n@patch(\"requests.get\")\ndef test_get_bulletin_from_web_failure(mock_get):\n    mock_get.return_value.status_code = 404\n    bulletin = get_bulletin_from_web()\n\n    assert bulletin == \"\"\n\n\n@patch(\"requests.get\")\ndef test_get_bulletin_from_web_exception(mock_get):\n    mock_get.side_effect = requests.exceptions.RequestException()\n    bulletin = get_bulletin_from_web()\n\n    assert bulletin == \"\"\n\n\ndef test_get_latest_bulletin_no_file():\n    if os.path.exists(\"data/CURRENT_BULLETIN.md\"):\n        os.remove(\"data/CURRENT_BULLETIN.md\")\n\n    bulletin, is_new = get_latest_bulletin()\n    assert is_new\n\n\ndef test_get_latest_bulletin_with_file():\n    expected_content = \"Test bulletin\"\n    with open(\"data/CURRENT_BULLETIN.md\", \"w\", encoding=\"utf-8\") as f:\n        f.write(expected_content)\n\n    with patch(\"autogpt.utils.get_bulletin_from_web\", return_value=\"\"):\n        bulletin, is_new = get_latest_bulletin()\n        assert expected_content in bulletin\n        assert is_new == False\n\n    os.remove(\"data/CURRENT_BULLETIN.md\")\n\n\ndef test_get_latest_bulletin_with_new_bulletin():\n    with open(\"data/CURRENT_BULLETIN.md\", \"w\", encoding=\"utf-8\") as f:\n        f.write(\"Old bulletin\")\n\n    expected_content = \"New bulletin from web\"\n    with patch(\"autogpt.utils.get_bulletin_from_web\", return_value=expected_content):\n        bulletin, is_new = get_latest_bulletin()\n        assert \"::NEW BULLETIN::\" in bulletin\n        assert expected_content in bulletin\n        assert is_new\n\n    os.remove(\"data/CURRENT_BULLETIN.md\")\n\n\ndef test_get_latest_bulletin_new_bulletin_same_as_old_bulletin():\n    expected_content = \"Current bulletin\"\n    with open(\"data/CURRENT_BULLETIN.md\", \"w\", encoding=\"utf-8\") as f:\n        f.write(expected_content)\n\n    with patch(\"autogpt.utils.get_bulletin_from_web\", return_value=expected_content):\n        bulletin, is_new = get_latest_bulletin()\n        assert expected_content in bulletin\n        assert is_new == False\n\n    os.remove(\"data/CURRENT_BULLETIN.md\")\n\n\n@skip_in_ci\ndef test_get_current_git_branch():\n    branch_name = get_current_git_branch()\n\n    # Assuming that the branch name will be non-empty if the function is working correctly.\n    assert branch_name != \"\"\n\n\n@patch(\"autogpt.utils.Repo\")\ndef test_get_current_git_branch_success(mock_repo):\n    mock_repo.return_value.active_branch.name = \"test-branch\"\n    branch_name = get_current_git_branch()\n\n    assert branch_name == \"test-branch\"\n\n\n@patch(\"autogpt.utils.Repo\")\ndef test_get_current_git_branch_failure(mock_repo):\n    mock_repo.side_effect = Exception()\n    branch_name = get_current_git_branch()\n\n    assert branch_name == \"\"\n\n\nif __name__ == \"__main__\":\n    pytest.main()\n"
  },
  {
    "path": "tests/test_workspace.py",
    "content": "import itertools\nfrom pathlib import Path\n\nimport pytest\n\nfrom autogpt.workspace import Workspace\n\n_WORKSPACE_ROOT = Path(\"home/users/monty/auto_gpt_workspace\")\n\n_ACCESSIBLE_PATHS = [\n    Path(\".\"),\n    Path(\"test_file.txt\"),\n    Path(\"test_folder\"),\n    Path(\"test_folder/test_file.txt\"),\n    Path(\"test_folder/..\"),\n    Path(\"test_folder/../test_file.txt\"),\n    Path(\"test_folder/../test_folder\"),\n    Path(\"test_folder/../test_folder/test_file.txt\"),\n]\n\n_INACCESSIBLE_PATHS = (\n    [\n        # Takes us out of the workspace\n        Path(\"..\"),\n        Path(\"../test_file.txt\"),\n        Path(\"../not_auto_gpt_workspace\"),\n        Path(\"../not_auto_gpt_workspace/test_file.txt\"),\n        Path(\"test_folder/../..\"),\n        Path(\"test_folder/../../test_file.txt\"),\n        Path(\"test_folder/../../not_auto_gpt_workspace\"),\n        Path(\"test_folder/../../not_auto_gpt_workspace/test_file.txt\"),\n    ]\n    + [\n        # Contains null bytes\n        Path(template.format(null_byte=null_byte))\n        for template, null_byte in itertools.product(\n            [\n                \"{null_byte}\",\n                \"{null_byte}test_file.txt\",\n                \"test_folder/{null_byte}\",\n                \"test_folder/{null_byte}test_file.txt\",\n            ],\n            Workspace.NULL_BYTES,\n        )\n    ]\n    + [\n        # Absolute paths\n        Path(\"/\"),\n        Path(\"/test_file.txt\"),\n        Path(\"/home\"),\n    ]\n)\n\n\n@pytest.fixture()\ndef workspace_root(tmp_path):\n    return tmp_path / _WORKSPACE_ROOT\n\n\n@pytest.fixture(params=_ACCESSIBLE_PATHS)\ndef accessible_path(request):\n    return request.param\n\n\n@pytest.fixture(params=_INACCESSIBLE_PATHS)\ndef inaccessible_path(request):\n    return request.param\n\n\ndef test_sanitize_path_accessible(accessible_path, workspace_root):\n    full_path = Workspace._sanitize_path(\n        accessible_path,\n        root=workspace_root,\n        restrict_to_root=True,\n    )\n    assert full_path.is_absolute()\n    assert full_path.is_relative_to(workspace_root)\n\n\ndef test_sanitize_path_inaccessible(inaccessible_path, workspace_root):\n    with pytest.raises(ValueError):\n        Workspace._sanitize_path(\n            inaccessible_path,\n            root=workspace_root,\n            restrict_to_root=True,\n        )\n\n\ndef test_get_path_accessible(accessible_path, workspace_root):\n    workspace = Workspace(workspace_root, True)\n    full_path = workspace.get_path(accessible_path)\n    assert full_path.is_absolute()\n    assert full_path.is_relative_to(workspace_root)\n\n\ndef test_get_path_inaccessible(inaccessible_path, workspace_root):\n    workspace = Workspace(workspace_root, True)\n    with pytest.raises(ValueError):\n        workspace.get_path(inaccessible_path)\n"
  },
  {
    "path": "tests/unit/__init__.py",
    "content": ""
  },
  {
    "path": "tests/unit/_test_json_parser.py",
    "content": "import unittest\n\nfrom autogpt.json_utils.json_fix_llm import fix_and_parse_json\n\n\nclass TestParseJson(unittest.TestCase):\n    def test_valid_json(self):\n        \"\"\"Test that a valid JSON string is parsed correctly.\"\"\"\n        json_str = '{\"name\": \"John\", \"age\": 30, \"city\": \"New York\"}'\n        obj = fix_and_parse_json(json_str)\n        self.assertEqual(obj, {\"name\": \"John\", \"age\": 30, \"city\": \"New York\"})\n\n    def test_invalid_json_minor(self):\n        \"\"\"Test that an invalid JSON string can be fixed with gpt.\"\"\"\n        json_str = '{\"name\": \"John\", \"age\": 30, \"city\": \"New York\",}'\n        self.assertEqual(\n            fix_and_parse_json(json_str, try_to_fix_with_gpt=False),\n            {\"name\": \"John\", \"age\": 30, \"city\": \"New York\"},\n        )\n\n    def test_invalid_json_major_with_gpt(self):\n        \"\"\"Test that an invalid JSON string raises an error when try_to_fix_with_gpt is False.\"\"\"\n        json_str = 'BEGIN: \"name\": \"John\" - \"age\": 30 - \"city\": \"New York\" :END'\n        self.assertEqual(\n            fix_and_parse_json(json_str, try_to_fix_with_gpt=True),\n            {\"name\": \"John\", \"age\": 30, \"city\": \"New York\"},\n        )\n\n    def test_invalid_json_major_without_gpt(self):\n        \"\"\"Test that a REALLY invalid JSON string raises an error when try_to_fix_with_gpt is False.\"\"\"\n        json_str = 'BEGIN: \"name\": \"John\" - \"age\": 30 - \"city\": \"New York\" :END'\n        # Assert that this raises an exception:\n        with self.assertRaises(Exception):\n            fix_and_parse_json(json_str, try_to_fix_with_gpt=False)\n\n    def test_invalid_json_leading_sentence_with_gpt(self):\n        \"\"\"Test that a REALLY invalid JSON string raises an error when try_to_fix_with_gpt is False.\"\"\"\n\n        json_str = \"\"\"I suggest we start by browsing the repository to find any issues that we can fix.\n\n{\n    \"command\": {\n        \"name\": \"browse_website\",\n        \"args\":{\n            \"url\": \"https://github.com/Torantulino/Auto-GPT\"\n        }\n    },\n    \"thoughts\":\n    {\n        \"text\": \"I suggest we start browsing the repository to find any issues that we can fix.\",\n        \"reasoning\": \"Browsing the repository will give us an idea of the current state of the codebase and identify any issues that we can address to improve the repo.\",\n        \"plan\": \"- Look through the repository to find any issues.\\n- Investigate any issues to determine what needs to be fixed\\n- Identify possible solutions to fix the issues\\n- Open Pull Requests with fixes\",\n        \"criticism\": \"I should be careful while browsing so as not to accidentally introduce any new bugs or issues.\",\n        \"speak\": \"I will start browsing the repository to find any issues we can fix.\"\n    }\n}\"\"\"\n        good_obj = {\n            \"command\": {\n                \"name\": \"browse_website\",\n                \"args\": {\"url\": \"https://github.com/Torantulino/Auto-GPT\"},\n            },\n            \"thoughts\": {\n                \"text\": \"I suggest we start browsing the repository to find any issues that we can fix.\",\n                \"reasoning\": \"Browsing the repository will give us an idea of the current state of the codebase and identify any issues that we can address to improve the repo.\",\n                \"plan\": \"- Look through the repository to find any issues.\\n- Investigate any issues to determine what needs to be fixed\\n- Identify possible solutions to fix the issues\\n- Open Pull Requests with fixes\",\n                \"criticism\": \"I should be careful while browsing so as not to accidentally introduce any new bugs or issues.\",\n                \"speak\": \"I will start browsing the repository to find any issues we can fix.\",\n            },\n        }\n        # Assert that this raises an exception:\n        self.assertEqual(\n            fix_and_parse_json(json_str, try_to_fix_with_gpt=False), good_obj\n        )\n\n    def test_invalid_json_leading_sentence_with_gpt(self):\n        \"\"\"Test that a REALLY invalid JSON string raises an error when try_to_fix_with_gpt is False.\"\"\"\n        json_str = \"\"\"I will first need to browse the repository (https://github.com/Torantulino/Auto-GPT) and identify any potential bugs that need fixing. I will use the \"browse_website\" command for this.\n\n{\n    \"command\": {\n        \"name\": \"browse_website\",\n        \"args\":{\n            \"url\": \"https://github.com/Torantulino/Auto-GPT\"\n        }\n    },\n    \"thoughts\":\n    {\n        \"text\": \"Browsing the repository to identify potential bugs\",\n        \"reasoning\": \"Before fixing bugs, I need to identify what needs fixing. I will use the 'browse_website' command to analyze the repository.\",\n        \"plan\": \"- Analyze the repository for potential bugs and areas of improvement\",\n        \"criticism\": \"I need to ensure I am thorough and pay attention to detail while browsing the repository.\",\n        \"speak\": \"I am browsing the repository to identify potential bugs.\"\n    }\n}\"\"\"\n        good_obj = {\n            \"command\": {\n                \"name\": \"browse_website\",\n                \"args\": {\"url\": \"https://github.com/Torantulino/Auto-GPT\"},\n            },\n            \"thoughts\": {\n                \"text\": \"Browsing the repository to identify potential bugs\",\n                \"reasoning\": \"Before fixing bugs, I need to identify what needs fixing. I will use the 'browse_website' command to analyze the repository.\",\n                \"plan\": \"- Analyze the repository for potential bugs and areas of improvement\",\n                \"criticism\": \"I need to ensure I am thorough and pay attention to detail while browsing the repository.\",\n                \"speak\": \"I am browsing the repository to identify potential bugs.\",\n            },\n        }\n        # Assert that this raises an exception:\n        self.assertEqual(\n            fix_and_parse_json(json_str, try_to_fix_with_gpt=False), good_obj\n        )\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "tests/unit/models/test_base_open_api_plugin.py",
    "content": "from typing import Any, Dict, List, Optional, Tuple\n\nimport pytest\n\nfrom autogpt.models.base_open_ai_plugin import (\n    BaseOpenAIPlugin,\n    Message,\n    PromptGenerator,\n)\n\n\nclass DummyPlugin(BaseOpenAIPlugin):\n    \"\"\"A dummy plugin for testing purposes.\"\"\"\n\n    pass\n\n\n@pytest.fixture\ndef dummy_plugin():\n    \"\"\"A dummy plugin for testing purposes.\"\"\"\n    manifests_specs_clients = {\n        \"manifest\": {\n            \"name_for_model\": \"Dummy\",\n            \"schema_version\": \"1.0\",\n            \"description_for_model\": \"A dummy plugin for testing purposes\",\n        },\n        \"client\": None,\n        \"openapi_spec\": None,\n    }\n    return DummyPlugin(manifests_specs_clients)\n\n\ndef test_dummy_plugin_inheritance(dummy_plugin):\n    \"\"\"Test that the DummyPlugin class inherits from the BaseOpenAIPlugin class.\"\"\"\n    assert isinstance(dummy_plugin, BaseOpenAIPlugin)\n\n\ndef test_dummy_plugin_name(dummy_plugin):\n    \"\"\"Test that the DummyPlugin class has the correct name.\"\"\"\n    assert dummy_plugin._name == \"Dummy\"\n\n\ndef test_dummy_plugin_version(dummy_plugin):\n    \"\"\"Test that the DummyPlugin class has the correct version.\"\"\"\n    assert dummy_plugin._version == \"1.0\"\n\n\ndef test_dummy_plugin_description(dummy_plugin):\n    \"\"\"Test that the DummyPlugin class has the correct description.\"\"\"\n    assert dummy_plugin._description == \"A dummy plugin for testing purposes\"\n\n\ndef test_dummy_plugin_default_methods(dummy_plugin):\n    \"\"\"Test that the DummyPlugin class has the correct default methods.\"\"\"\n    assert not dummy_plugin.can_handle_on_response()\n    assert not dummy_plugin.can_handle_post_prompt()\n    assert not dummy_plugin.can_handle_on_planning()\n    assert not dummy_plugin.can_handle_post_planning()\n    assert not dummy_plugin.can_handle_pre_instruction()\n    assert not dummy_plugin.can_handle_on_instruction()\n    assert not dummy_plugin.can_handle_post_instruction()\n    assert not dummy_plugin.can_handle_pre_command()\n    assert not dummy_plugin.can_handle_post_command()\n    assert not dummy_plugin.can_handle_chat_completion(None, None, None, None)\n\n    assert dummy_plugin.on_response(\"hello\") == \"hello\"\n    assert dummy_plugin.post_prompt(None) is None\n    assert dummy_plugin.on_planning(None, None) is None\n    assert dummy_plugin.post_planning(\"world\") == \"world\"\n    pre_instruction = dummy_plugin.pre_instruction(\n        [{\"role\": \"system\", \"content\": \"Beep, bop, boop\"}]\n    )\n    assert isinstance(pre_instruction, list)\n    assert len(pre_instruction) == 1\n    assert pre_instruction[0][\"role\"] == \"system\"\n    assert pre_instruction[0][\"content\"] == \"Beep, bop, boop\"\n    assert dummy_plugin.on_instruction(None) is None\n    assert dummy_plugin.post_instruction(\"I'm a robot\") == \"I'm a robot\"\n    pre_command = dummy_plugin.pre_command(\"evolve\", {\"continuously\": True})\n    assert isinstance(pre_command, tuple)\n    assert len(pre_command) == 2\n    assert pre_command[0] == \"evolve\"\n    assert pre_command[1][\"continuously\"] == True\n    post_command = dummy_plugin.post_command(\"evolve\", \"upgraded successfully!\")\n    assert isinstance(post_command, str)\n    assert post_command == \"upgraded successfully!\"\n    assert dummy_plugin.handle_chat_completion(None, None, None, None) is None\n"
  },
  {
    "path": "tests/unit/test_browse_scrape_links.py",
    "content": "# Generated by CodiumAI\n\n# Dependencies:\n# pip install pytest-mock\nimport pytest\n\nfrom autogpt.commands.web_requests import scrape_links\n\n\"\"\"\nCode Analysis\n\nObjective:\nThe objective of the 'scrape_links' function is to scrape hyperlinks from a\ngiven URL and return them in a formatted way.\n\nInputs:\n- url: a string representing the URL to be scraped.\n\nFlow:\n1. Send a GET request to the given URL using the requests library and the user agent header from the config file.\n2. Check if the response contains an HTTP error. If it does, return \"error\".\n3. Parse the HTML content of the response using the BeautifulSoup library.\n4. Remove any script and style tags from the parsed HTML.\n5. Extract all hyperlinks from the parsed HTML using the 'extract_hyperlinks' function.\n6. Format the extracted hyperlinks using the 'format_hyperlinks' function.\n7. Return the formatted hyperlinks.\n\nOutputs:\n- A list of formatted hyperlinks.\n\nAdditional aspects:\n- The function uses the 'requests' and 'BeautifulSoup' libraries to send HTTP\nrequests and parse HTML content, respectively.\n- The 'extract_hyperlinks' function is called to extract hyperlinks from the parsed HTML.\n- The 'format_hyperlinks' function is called to format the extracted hyperlinks.\n- The function checks for HTTP errors and returns \"error\" if any are found.\n\"\"\"\n\n\nclass TestScrapeLinks:\n    \"\"\"\n    Tests that the function returns a list of formatted hyperlinks when\n    provided with a valid url that returns a webpage with hyperlinks.\n    \"\"\"\n\n    def test_valid_url_with_hyperlinks(self):\n        url = \"https://www.google.com\"\n        result = scrape_links(url)\n        assert len(result) > 0\n        assert isinstance(result, list)\n        assert isinstance(result[0], str)\n\n    def test_valid_url(self, mocker):\n        \"\"\"Test that the function returns correctly formatted hyperlinks when given a valid url.\"\"\"\n        # Mock the requests.get() function to return a response with sample HTML containing hyperlinks\n        mock_response = mocker.Mock()\n        mock_response.status_code = 200\n        mock_response.text = (\n            \"<html><body><a href='https://www.google.com'>Google</a></body></html>\"\n        )\n        mocker.patch(\"requests.Session.get\", return_value=mock_response)\n\n        # Call the function with a valid URL\n        result = scrape_links(\"https://www.example.com\")\n\n        # Assert that the function returns correctly formatted hyperlinks\n        assert result == [\"Google (https://www.google.com)\"]\n\n    def test_invalid_url(self, mocker):\n        \"\"\"Test that the function returns \"error\" when given an invalid url.\"\"\"\n        # Mock the requests.get() function to return an HTTP error response\n        mock_response = mocker.Mock()\n        mock_response.status_code = 404\n        mocker.patch(\"requests.Session.get\", return_value=mock_response)\n\n        # Call the function with an invalid URL\n        result = scrape_links(\"https://www.invalidurl.com\")\n\n        # Assert that the function returns \"error\"\n        assert \"Error:\" in result\n\n    def test_no_hyperlinks(self, mocker):\n        \"\"\"Test that the function returns an empty list when the html contains no hyperlinks.\"\"\"\n        # Mock the requests.get() function to return a response with sample HTML containing no hyperlinks\n        mock_response = mocker.Mock()\n        mock_response.status_code = 200\n        mock_response.text = \"<html><body><p>No hyperlinks here</p></body></html>\"\n        mocker.patch(\"requests.Session.get\", return_value=mock_response)\n\n        # Call the function with a URL containing no hyperlinks\n        result = scrape_links(\"https://www.example.com\")\n\n        # Assert that the function returns an empty list\n        assert result == []\n\n    def test_scrape_links_with_few_hyperlinks(self, mocker):\n        \"\"\"Test that scrape_links() correctly extracts and formats hyperlinks from a sample HTML containing a few hyperlinks.\"\"\"\n        mock_response = mocker.Mock()\n        mock_response.status_code = 200\n        mock_response.text = \"\"\"\n            <html>\n                <body>\n                    <div id=\"google-link\"><a href=\"https://www.google.com\">Google</a></div>\n                    <div id=\"github\"><a href=\"https://github.com\">GitHub</a></div>\n                    <div id=\"CodiumAI\"><a href=\"https://www.codium.ai\">CodiumAI</a></div>\n                </body>\n            </html>\n        \"\"\"\n        mocker.patch(\"requests.Session.get\", return_value=mock_response)\n\n        # Call the function being tested\n        result = scrape_links(\"https://www.example.com\")\n\n        # Assert that the function returns a list of formatted hyperlinks\n        assert isinstance(result, list)\n        assert len(result) == 3\n        assert result[0] == \"Google (https://www.google.com)\"\n        assert result[1] == \"GitHub (https://github.com)\"\n        assert result[2] == \"CodiumAI (https://www.codium.ai)\"\n"
  },
  {
    "path": "tests/unit/test_browse_scrape_text.py",
    "content": "# Generated by CodiumAI\n\nimport pytest\nimport requests\n\nfrom autogpt.commands.web_requests import scrape_text\n\n\"\"\"\nCode Analysis\n\nObjective:\nThe objective of the \"scrape_text\" function is to scrape the text content from\na given URL and return it as a string, after removing any unwanted HTML tags and\n scripts.\n\nInputs:\n- url: a string representing the URL of the webpage to be scraped.\n\nFlow:\n1. Send a GET request to the given URL using the requests library and the user agent\n header from the config file.\n2. Check if the response contains an HTTP error. If it does, return an error message.\n3. Use BeautifulSoup to parse the HTML content of the response and extract all script\n and style tags.\n4. Get the text content of the remaining HTML using the get_text() method of\n BeautifulSoup.\n5. Split the text into lines and then into chunks, removing any extra whitespace.\n6. Join the chunks into a single string with newline characters between them.\n7. Return the cleaned text.\n\nOutputs:\n- A string representing the cleaned text content of the webpage.\n\nAdditional aspects:\n- The function uses the requests library and BeautifulSoup to handle the HTTP request\n and HTML parsing, respectively.\n- The function removes script and style tags from the HTML to avoid including unwanted\n content in the text output.\n- The function uses a generator expression to split the text into lines and chunks,\n which can improve performance for large amounts of text.\n\"\"\"\n\n\nclass TestScrapeText:\n    def test_scrape_text_with_valid_url(self, mocker):\n        \"\"\"Tests that scrape_text() returns the expected text when given a valid URL.\"\"\"\n        # Mock the requests.get() method to return a response with expected text\n        expected_text = \"This is some sample text\"\n        mock_response = mocker.Mock()\n        mock_response.status_code = 200\n        mock_response.text = (\n            \"<html><body><div><p style='color: blue;'>\"\n            f\"{expected_text}</p></div></body></html>\"\n        )\n        mocker.patch(\"requests.Session.get\", return_value=mock_response)\n\n        # Call the function with a valid URL and assert that it returns the\n        #  expected text\n        url = \"http://www.example.com\"\n        assert scrape_text(url) == expected_text\n\n    def test_invalid_url(self):\n        \"\"\"Tests that an error is raised when an invalid url is provided.\"\"\"\n        url = \"invalidurl.com\"\n        pytest.raises(ValueError, scrape_text, url)\n\n    def test_unreachable_url(self, mocker):\n        \"\"\"Test that scrape_text returns an error message when an invalid or unreachable url is provided.\"\"\"\n        # Mock the requests.get() method to raise an exception\n        mocker.patch(\n            \"requests.Session.get\", side_effect=requests.exceptions.RequestException\n        )\n\n        # Call the function with an invalid URL and assert that it returns an error\n        #  message\n        url = \"http://thiswebsitedoesnotexist.net/\"\n        error_message = scrape_text(url)\n        assert \"Error:\" in error_message\n\n    def test_no_text(self, mocker):\n        \"\"\"Test that scrape_text returns an empty string when the html page contains no text to be scraped.\"\"\"\n        # Mock the requests.get() method to return a response with no text\n        mock_response = mocker.Mock()\n        mock_response.status_code = 200\n        mock_response.text = \"<html><body></body></html>\"\n        mocker.patch(\"requests.Session.get\", return_value=mock_response)\n\n        # Call the function with a valid URL and assert that it returns an empty string\n        url = \"http://www.example.com\"\n        assert scrape_text(url) == \"\"\n\n    def test_http_error(self, mocker):\n        \"\"\"Test that scrape_text returns an error message when the response status code is an http error (>=400).\"\"\"\n        # Mock the requests.get() method to return a response with a 404 status code\n        mocker.patch(\"requests.Session.get\", return_value=mocker.Mock(status_code=404))\n\n        # Call the function with a URL\n        result = scrape_text(\"https://www.example.com\")\n\n        # Check that the function returns an error message\n        assert result == \"Error: HTTP 404 error\"\n\n    def test_scrape_text_with_html_tags(self, mocker):\n        \"\"\"Test that scrape_text() properly handles HTML tags.\"\"\"\n        # Create a mock response object with HTML containing tags\n        html = \"<html><body><p>This is <b>bold</b> text.</p></body></html>\"\n        mock_response = mocker.Mock()\n        mock_response.status_code = 200\n        mock_response.text = html\n        mocker.patch(\"requests.Session.get\", return_value=mock_response)\n\n        # Call the function with a URL\n        result = scrape_text(\"https://www.example.com\")\n\n        # Check that the function properly handles HTML tags\n        assert result == \"This is bold text.\"\n"
  },
  {
    "path": "tests/unit/test_chat.py",
    "content": "# Generated by CodiumAI\nimport time\nfrom unittest.mock import patch\n\nfrom autogpt.llm import create_chat_message, generate_context\n\n\ndef test_happy_path_role_content():\n    \"\"\"Test that the function returns a dictionary with the correct keys and values when valid strings are provided for role and content.\"\"\"\n    result = create_chat_message(\"system\", \"Hello, world!\")\n    assert result == {\"role\": \"system\", \"content\": \"Hello, world!\"}\n\n\ndef test_empty_role_content():\n    \"\"\"Test that the function returns a dictionary with the correct keys and values when empty strings are provided for role and content.\"\"\"\n    result = create_chat_message(\"\", \"\")\n    assert result == {\"role\": \"\", \"content\": \"\"}\n\n\ndef test_generate_context_empty_inputs(mocker):\n    \"\"\"Test the behavior of the generate_context function when all input parameters are empty.\"\"\"\n    # Mock the time.strftime function to return a fixed value\n    mocker.patch(\"time.strftime\", return_value=\"Sat Apr 15 00:00:00 2023\")\n    # Arrange\n    prompt = \"\"\n    relevant_memory = \"\"\n    full_message_history = []\n    model = \"gpt-3.5-turbo-0301\"\n\n    # Act\n    result = generate_context(prompt, relevant_memory, full_message_history, model)\n\n    # Assert\n    expected_result = (\n        -1,\n        32,\n        2,\n        [\n            {\"role\": \"system\", \"content\": \"\"},\n            {\n                \"role\": \"system\",\n                \"content\": f\"当前的日期和时间是 {time.strftime('%c')}\",\n            },\n        ],\n    )\n    assert result == expected_result\n\n\ndef test_generate_context_valid_inputs():\n    \"\"\"Test that the function successfully generates a current_context given valid inputs.\"\"\"\n    # Given\n    prompt = \"What is your favorite color?\"\n    relevant_memory = \"You once painted your room blue.\"\n    full_message_history = [\n        create_chat_message(\"user\", \"Hi there!\"),\n        create_chat_message(\"assistant\", \"Hello! How can I assist you today?\"),\n        create_chat_message(\"user\", \"Can you tell me a joke?\"),\n        create_chat_message(\n            \"assistant\",\n            \"Why did the tomato turn red? Because it saw the salad dressing!\",\n        ),\n        create_chat_message(\"user\", \"Haha, that's funny.\"),\n    ]\n    model = \"gpt-3.5-turbo-0301\"\n\n    # When\n    result = generate_context(prompt, relevant_memory, full_message_history, model)\n\n    # Then\n    assert isinstance(result[0], int)\n    assert isinstance(result[1], int)\n    assert isinstance(result[2], int)\n    assert isinstance(result[3], list)\n    assert result[0] >= 0\n    assert result[2] >= 0\n    assert result[1] >= 0\n    assert len(result[3]) >= 2  # current_context should have at least 2 messages\n    assert result[1] <= 2048  # token limit for GPT-3.5-turbo-0301 is 2048 tokens\n"
  },
  {
    "path": "tests/unit/test_commands.py",
    "content": "\"\"\"Unit tests for the commands module\"\"\"\nfrom unittest.mock import MagicMock, patch\n\nimport pytest\n\nfrom autogpt.app import list_agents, start_agent\nfrom tests.utils import requires_api_key\n\n\n@pytest.mark.vcr\n@pytest.mark.integration_test\n@requires_api_key(\"OPENAI_API_KEY\")\ndef test_make_agent() -> None:\n    \"\"\"Test that an agent can be created\"\"\"\n    # Use the mock agent manager to avoid creating a real agent\n    with patch(\"openai.ChatCompletion.create\") as mock:\n        response = MagicMock()\n        response.choices[0].messages[0].content = \"Test message\"\n        response.usage.prompt_tokens = 1\n        response.usage.completion_tokens = 1\n        mock.return_value = response\n        start_agent(\"Test Agent\", \"chat\", \"Hello, how are you?\", \"gpt-3.5-turbo\")\n        agents = list_agents()\n        assert \"List of agents:\\n0: chat\" == agents\n        start_agent(\"Test Agent 2\", \"write\", \"Hello, how are you?\", \"gpt-3.5-turbo\")\n        agents = list_agents()\n        assert \"List of agents:\\n0: chat\\n1: write\" == agents\n"
  },
  {
    "path": "tests/unit/test_file_operations.py",
    "content": "\"\"\"\nThis set of unit tests is designed to test the file operations that autoGPT has access to.\n\"\"\"\n\nimport hashlib\nimport os\nimport re\nfrom io import TextIOWrapper\nfrom pathlib import Path\n\nimport pytest\nfrom pytest_mock import MockerFixture\n\nimport autogpt.commands.file_operations as file_ops\nfrom autogpt.config import Config\nfrom autogpt.utils import readable_file_size\nfrom autogpt.workspace import Workspace\n\n\n@pytest.fixture()\ndef file_content():\n    return \"This is a test file.\\n\"\n\n\n@pytest.fixture()\ndef test_file_path(config, workspace: Workspace):\n    return workspace.get_path(\"test_file.txt\")\n\n\n@pytest.fixture()\ndef test_file(test_file_path: Path):\n    file = open(test_file_path, \"w\")\n    yield file\n    if not file.closed:\n        file.close()\n\n\n@pytest.fixture()\ndef test_file_with_content_path(test_file: TextIOWrapper, file_content):\n    test_file.write(file_content)\n    test_file.close()\n    file_ops.log_operation(\n        \"write\", test_file.name, file_ops.text_checksum(file_content)\n    )\n    return Path(test_file.name)\n\n\n@pytest.fixture()\ndef test_directory(config, workspace: Workspace):\n    return workspace.get_path(\"test_directory\")\n\n\n@pytest.fixture()\ndef test_nested_file(config, workspace: Workspace):\n    return workspace.get_path(\"nested/test_file.txt\")\n\n\ndef test_file_operations_log(test_file: TextIOWrapper):\n    log_file_content = (\n        \"File Operation Logger\\n\"\n        \"write: path/to/file1.txt #checksum1\\n\"\n        \"write: path/to/file2.txt #checksum2\\n\"\n        \"write: path/to/file3.txt #checksum3\\n\"\n        \"append: path/to/file2.txt #checksum4\\n\"\n        \"delete: path/to/file3.txt\\n\"\n    )\n    test_file.write(log_file_content)\n    test_file.close()\n\n    expected = [\n        (\"write\", \"path/to/file1.txt\", \"checksum1\"),\n        (\"write\", \"path/to/file2.txt\", \"checksum2\"),\n        (\"write\", \"path/to/file3.txt\", \"checksum3\"),\n        (\"append\", \"path/to/file2.txt\", \"checksum4\"),\n        (\"delete\", \"path/to/file3.txt\", None),\n    ]\n    assert list(file_ops.operations_from_log(test_file.name)) == expected\n\n\ndef test_file_operations_state(test_file: TextIOWrapper):\n    # Prepare a fake log file\n    log_file_content = (\n        \"File Operation Logger\\n\"\n        \"write: path/to/file1.txt #checksum1\\n\"\n        \"write: path/to/file2.txt #checksum2\\n\"\n        \"write: path/to/file3.txt #checksum3\\n\"\n        \"append: path/to/file2.txt #checksum4\\n\"\n        \"delete: path/to/file3.txt\\n\"\n    )\n    test_file.write(log_file_content)\n    test_file.close()\n\n    # Call the function and check the returned dictionary\n    expected_state = {\n        \"path/to/file1.txt\": \"checksum1\",\n        \"path/to/file2.txt\": \"checksum4\",\n    }\n    assert file_ops.file_operations_state(test_file.name) == expected_state\n\n\ndef test_is_duplicate_operation(config, mocker: MockerFixture):\n    # Prepare a fake state dictionary for the function to use\n    state = {\n        \"path/to/file1.txt\": \"checksum1\",\n        \"path/to/file2.txt\": \"checksum2\",\n    }\n    mocker.patch.object(file_ops, \"file_operations_state\", lambda _: state)\n\n    # Test cases with write operations\n    assert (\n        file_ops.is_duplicate_operation(\"write\", \"path/to/file1.txt\", \"checksum1\")\n        is True\n    )\n    assert (\n        file_ops.is_duplicate_operation(\"write\", \"path/to/file1.txt\", \"checksum2\")\n        is False\n    )\n    assert (\n        file_ops.is_duplicate_operation(\"write\", \"path/to/file3.txt\", \"checksum3\")\n        is False\n    )\n    # Test cases with append operations\n    assert (\n        file_ops.is_duplicate_operation(\"append\", \"path/to/file1.txt\", \"checksum1\")\n        is False\n    )\n    # Test cases with delete operations\n    assert file_ops.is_duplicate_operation(\"delete\", \"path/to/file1.txt\") is False\n    assert file_ops.is_duplicate_operation(\"delete\", \"path/to/file3.txt\") is True\n\n\n# Test logging a file operation\ndef test_log_operation(config: Config):\n    file_ops.log_operation(\"log_test\", \"path/to/test\")\n    with open(config.file_logger_path, \"r\", encoding=\"utf-8\") as f:\n        content = f.read()\n    assert f\"log_test: path/to/test\\n\" in content\n\n\ndef test_text_checksum(file_content: str):\n    checksum = file_ops.text_checksum(file_content)\n    different_checksum = file_ops.text_checksum(\"other content\")\n    assert re.match(r\"^[a-fA-F0-9]+$\", checksum) is not None\n    assert checksum != different_checksum\n\n\ndef test_log_operation_with_checksum(config: Config):\n    file_ops.log_operation(\"log_test\", \"path/to/test\", checksum=\"ABCDEF\")\n    with open(config.file_logger_path, \"r\", encoding=\"utf-8\") as f:\n        content = f.read()\n    assert f\"log_test: path/to/test #ABCDEF\\n\" in content\n\n\n# Test splitting a file into chunks\ndef test_split_file():\n    content = \"abcdefghij\"\n    chunks = list(file_ops.split_file(content, max_length=4, overlap=1))\n    expected = [\"abcd\", \"defg\", \"ghij\"]\n    assert chunks == expected\n\n\ndef test_read_file(test_file_with_content_path: Path, file_content):\n    content = file_ops.read_file(test_file_with_content_path)\n    assert content == file_content\n\n\ndef test_write_to_file(test_file_path: Path):\n    new_content = \"This is new content.\\n\"\n    file_ops.write_to_file(str(test_file_path), new_content)\n    with open(test_file_path, \"r\", encoding=\"utf-8\") as f:\n        content = f.read()\n    assert content == new_content\n\n\ndef test_write_file_logs_checksum(config: Config, test_file_path: Path):\n    new_content = \"This is new content.\\n\"\n    new_checksum = file_ops.text_checksum(new_content)\n    file_ops.write_to_file(str(test_file_path), new_content)\n    with open(config.file_logger_path, \"r\", encoding=\"utf-8\") as f:\n        log_entry = f.read()\n    assert log_entry == f\"write: {test_file_path} #{new_checksum}\\n\"\n\n\ndef test_write_file_fails_if_content_exists(test_file_path: Path):\n    new_content = \"This is new content.\\n\"\n    file_ops.log_operation(\n        \"write\",\n        str(test_file_path),\n        checksum=file_ops.text_checksum(new_content),\n    )\n    result = file_ops.write_to_file(str(test_file_path), new_content)\n    assert result == \"Error: File has already been updated.\"\n\n\ndef test_write_file_succeeds_if_content_different(test_file_with_content_path: Path):\n    new_content = \"This is different content.\\n\"\n    result = file_ops.write_to_file(str(test_file_with_content_path), new_content)\n    assert result == \"File written to successfully.\"\n\n\ndef test_append_to_file(test_nested_file: Path):\n    append_text = \"This is appended text.\\n\"\n    file_ops.write_to_file(test_nested_file, append_text)\n\n    file_ops.append_to_file(test_nested_file, append_text)\n\n    with open(test_nested_file, \"r\") as f:\n        content_after = f.read()\n\n    assert content_after == append_text + append_text\n\n\ndef test_append_to_file_uses_checksum_from_appended_file(\n    config: Config, test_file_path: Path\n):\n    append_text = \"This is appended text.\\n\"\n    file_ops.append_to_file(test_file_path, append_text)\n    file_ops.append_to_file(test_file_path, append_text)\n    with open(config.file_logger_path, \"r\", encoding=\"utf-8\") as f:\n        log_contents = f.read()\n\n    digest = hashlib.md5()\n    digest.update(append_text.encode(\"utf-8\"))\n    checksum1 = digest.hexdigest()\n    digest.update(append_text.encode(\"utf-8\"))\n    checksum2 = digest.hexdigest()\n    assert log_contents == (\n        f\"append: {test_file_path} #{checksum1}\\n\"\n        f\"append: {test_file_path} #{checksum2}\\n\"\n    )\n\n\ndef test_delete_file(test_file_with_content_path: Path):\n    result = file_ops.delete_file(str(test_file_with_content_path))\n    assert result == \"File deleted successfully.\"\n    assert os.path.exists(test_file_with_content_path) is False\n\n\ndef test_delete_missing_file(config):\n    filename = \"path/to/file/which/does/not/exist\"\n    # confuse the log\n    file_ops.log_operation(\"write\", filename, checksum=\"fake\")\n    try:\n        os.remove(filename)\n    except FileNotFoundError as err:\n        assert str(err) in file_ops.delete_file(filename)\n        return\n    assert False, f\"Failed to test delete_file; {filename} not expected to exist\"\n\n\ndef test_list_files(workspace: Workspace, test_directory: Path):\n    # Case 1: Create files A and B, search for A, and ensure we don't return A and B\n    file_a = workspace.get_path(\"file_a.txt\")\n    file_b = workspace.get_path(\"file_b.txt\")\n\n    with open(file_a, \"w\") as f:\n        f.write(\"This is file A.\")\n\n    with open(file_b, \"w\") as f:\n        f.write(\"This is file B.\")\n\n    # Create a subdirectory and place a copy of file_a in it\n    if not os.path.exists(test_directory):\n        os.makedirs(test_directory)\n\n    with open(os.path.join(test_directory, file_a.name), \"w\") as f:\n        f.write(\"This is file A in the subdirectory.\")\n\n    files = file_ops.list_files(str(workspace.root))\n    assert file_a.name in files\n    assert file_b.name in files\n    assert os.path.join(Path(test_directory).name, file_a.name) in files\n\n    # Clean up\n    os.remove(file_a)\n    os.remove(file_b)\n    os.remove(os.path.join(test_directory, file_a.name))\n    os.rmdir(test_directory)\n\n    # Case 2: Search for a file that does not exist and make sure we don't throw\n    non_existent_file = \"non_existent_file.txt\"\n    files = file_ops.list_files(\"\")\n    assert non_existent_file not in files\n\n\ndef test_download_file(config, workspace: Workspace):\n    url = \"https://github.com/Significant-Gravitas/Auto-GPT/archive/refs/tags/v0.2.2.tar.gz\"\n    local_name = workspace.get_path(\"auto-gpt.tar.gz\")\n    size = 365023\n    readable_size = readable_file_size(size)\n    assert (\n        file_ops.download_file(url, local_name)\n        == f'Successfully downloaded and locally stored file: \"{local_name}\"! (Size: {readable_size})'\n    )\n    assert os.path.isfile(local_name) is True\n    assert os.path.getsize(local_name) == size\n\n    url = \"https://github.com/Significant-Gravitas/Auto-GPT/archive/refs/tags/v0.0.0.tar.gz\"\n    assert \"Got an HTTP Error whilst trying to download file\" in file_ops.download_file(\n        url, local_name\n    )\n\n    url = \"https://thiswebsiteiswrong.hmm/v0.0.0.tar.gz\"\n    assert \"Failed to establish a new connection:\" in file_ops.download_file(\n        url, local_name\n    )\n"
  },
  {
    "path": "tests/unit/test_get_self_feedback.py",
    "content": "from autogpt.agent.agent import Agent\nfrom autogpt.config import AIConfig\nfrom autogpt.llm import create_chat_completion\n\n\ndef test_get_self_feedback(mocker):\n    # Define a sample thoughts dictionary\n    thoughts = {\n        \"reasoning\": \"Sample reasoning.\",\n        \"plan\": \"Sample plan.\",\n        \"thoughts\": \"Sample thoughts.\",\n    }\n\n    # Define a fake response for the create_chat_completion function\n    fake_response = (\n        \"The AI Agent has demonstrated a reasonable thought process, but there is room for improvement. \"\n        \"For example, the reasoning could be elaborated to better justify the plan, and the plan itself \"\n        \"could be more detailed to ensure its effectiveness. In addition, the AI Agent should focus more \"\n        \"on its core role and prioritize thoughts that align with that role.\"\n    )\n\n    # Mock the create_chat_completion function\n    mock_create_chat_completion = mocker.patch(\n        \"autogpt.agent.agent.create_chat_completion\", wraps=create_chat_completion\n    )\n    mock_create_chat_completion.return_value = fake_response\n\n    # Create a MagicMock object to replace the Agent instance\n    agent_mock = mocker.MagicMock(spec=Agent)\n\n    # Mock the config attribute of the Agent instance\n    agent_mock.config = AIConfig()\n\n    # Call the get_self_feedback method\n    feedback = Agent.get_self_feedback(\n        agent_mock,\n        thoughts,\n        \"gpt-3.5-turbo\",\n    )\n\n    # Check if the response is a non-empty string\n    assert isinstance(feedback, str) and len(feedback) > 0\n\n    # Check if certain keywords from input thoughts are present in the feedback response\n    for keyword in [\"reasoning\", \"plan\", \"thoughts\"]:\n        assert keyword in feedback\n"
  },
  {
    "path": "tests/unit/test_json_parser.py",
    "content": "from unittest import TestCase\n\nfrom autogpt.json_utils.json_fix_llm import fix_and_parse_json\nfrom tests.utils import skip_in_ci\n\n\nclass TestParseJson(TestCase):\n    def test_valid_json(self):\n        \"\"\"Test that a valid JSON string is parsed correctly.\"\"\"\n        json_str = '{\"name\": \"John\", \"age\": 30, \"city\": \"New York\"}'\n        obj = fix_and_parse_json(json_str)\n        self.assertEqual(obj, {\"name\": \"John\", \"age\": 30, \"city\": \"New York\"})\n\n    def test_invalid_json_minor(self):\n        \"\"\"Test that an invalid JSON string can not be fixed without gpt\"\"\"\n        json_str = '{\"name\": \"John\", \"age\": 30, \"city\": \"New York\",}'\n        with self.assertRaises(Exception):\n            fix_and_parse_json(json_str, try_to_fix_with_gpt=False)\n\n    def test_invalid_json_major_with_gpt(self):\n        \"\"\"Test that an invalid JSON string raises an error when try_to_fix_with_gpt is False\"\"\"\n        json_str = 'BEGIN: \"name\": \"John\" - \"age\": 30 - \"city\": \"New York\" :END'\n        with self.assertRaises(Exception):\n            fix_and_parse_json(json_str, try_to_fix_with_gpt=False)\n\n    def test_invalid_json_major_without_gpt(self):\n        \"\"\"Test that a REALLY invalid JSON string raises an error when try_to_fix_with_gpt is False\"\"\"\n        json_str = 'BEGIN: \"name\": \"John\" - \"age\": 30 - \"city\": \"New York\" :END'\n        # Assert that this raises an exception:\n        with self.assertRaises(Exception):\n            fix_and_parse_json(json_str, try_to_fix_with_gpt=False)\n\n    def test_invalid_json_leading_sentence_with_gpt(self):\n        \"\"\"Test that a REALLY invalid JSON string raises an error when try_to_fix_with_gpt is False\"\"\"\n        json_str = \"\"\"I suggest we start by browsing the repository to find any issues that we can fix.\n\n{\n    \"command\": {\n        \"name\": \"browse_website\",\n        \"args\":{\n            \"url\": \"https://github.com/Torantulino/Auto-GPT\"\n        }\n    },\n    \"thoughts\":\n    {\n        \"text\": \"I suggest we start browsing the repository to find any issues that we can fix.\",\n        \"reasoning\": \"Browsing the repository will give us an idea of the current state of the codebase and identify any issues that we can address to improve the repo.\",\n        \"plan\": \"- Look through the repository to find any issues.\\n- Investigate any issues to determine what needs to be fixed\\n- Identify possible solutions to fix the issues\\n- Open Pull Requests with fixes\",\n        \"criticism\": \"I should be careful while browsing so as not to accidentally introduce any new bugs or issues.\",\n        \"speak\": \"I will start browsing the repository to find any issues we can fix.\"\n    }\n}\"\"\"\n        good_obj = {\n            \"command\": {\n                \"name\": \"browse_website\",\n                \"args\": {\"url\": \"https://github.com/Torantulino/Auto-GPT\"},\n            },\n            \"thoughts\": {\n                \"text\": \"I suggest we start browsing the repository to find any issues that we can fix.\",\n                \"reasoning\": \"Browsing the repository will give us an idea of the current state of the codebase and identify any issues that we can address to improve the repo.\",\n                \"plan\": \"- Look through the repository to find any issues.\\n- Investigate any issues to determine what needs to be fixed\\n- Identify possible solutions to fix the issues\\n- Open Pull Requests with fixes\",\n                \"criticism\": \"I should be careful while browsing so as not to accidentally introduce any new bugs or issues.\",\n                \"speak\": \"I will start browsing the repository to find any issues we can fix.\",\n            },\n        }\n\n        # # Assert that this can be fixed with GPT\n        # self.assertEqual(fix_and_parse_json(json_str), good_obj)\n\n        # Assert that trying to fix this without GPT raises an exception\n        with self.assertRaises(Exception):\n            fix_and_parse_json(json_str, try_to_fix_with_gpt=False)\n"
  },
  {
    "path": "tests/unit/test_json_utils_llm.py",
    "content": "# Generated by CodiumAI\nimport pytest\nfrom loguru import logger\n\nfrom autogpt.json_utils.json_fix_llm import (\n    fix_and_parse_json,\n    fix_json_using_multiple_techniques,\n)\nfrom tests.utils import requires_api_key\n\n\"\"\"\nCode Analysis\n\nObjective:\n- The objective of the function is to fix a given JSON string to make it parseable and fully compliant with two techniques.\n\nInputs:\n- The function takes in a string called 'assistant_reply', which is the JSON string to be fixed.\n\nFlow:\n- The function first calls the 'fix_and_parse_json' function to parse and print the Assistant response.\n- If the parsed JSON is an empty dictionary, the function calls the 'attempt_to_fix_json_by_finding_outermost_brackets' function to fix the JSON string.\n- If the parsed JSON is not an empty dictionary, the function returns the parsed JSON.\n- If the parsed JSON is an empty dictionary and cannot be fixed, the function logs an error and returns an empty dictionary.\n\nOutputs:\n- The main output of the function is a dictionary containing the fixed JSON string.\n\nAdditional aspects:\n- The function uses two techniques to fix the JSON string: parsing and finding outermost brackets.\n- The function logs an error if the JSON string cannot be fixed and returns an empty dictionary.\n- The function uses the 'CFG' object to determine whether to speak the error message or not.\n\"\"\"\n\n\nclass TestFixJsonUsingMultipleTechniques:\n    # Tests that the function successfully fixes and parses a JSON string that is already compliant with both techniques.\n    def test_fix_and_parse_json_happy_path(self):\n        # Happy path test case where the JSON string is already compliant with both techniques\n        json_string = '{\"text\": \"Hello world\", \"confidence\": 0.9}'\n        expected_output = {\"text\": \"Hello world\", \"confidence\": 0.9}\n        assert fix_json_using_multiple_techniques(json_string) == expected_output\n\n    # Tests that the function successfully fixes and parses a JSON string that contains only whitespace characters.\n    # @requires_api_key(\"OPEN_API_KEY\")\n    def test_fix_and_parse_json_whitespace(self, mocker):\n        # Happy path test case where the JSON string contains only whitespace characters\n        json_string = \"   \\n\\t   \"\n\n        # mock try_ai_fix to avoid calling the AI model:\n        mocker.patch(\"autogpt.json_utils.json_fix_llm.try_ai_fix\", return_value={})\n\n        expected_output = {}\n        assert fix_json_using_multiple_techniques(json_string) == expected_output\n\n    # Tests that the function successfully converts a string with arrays to an array\n    def test_fix_and_parse_json_array(self):\n        # Happy path test case where the JSON string contains an array of string\n        json_string = '[ \"Add type hints\", \"Move docstrings\", \"Consider using\" ]'\n        expected_output = [\"Add type hints\", \"Move docstrings\", \"Consider using\"]\n        assert fix_json_using_multiple_techniques(json_string) == expected_output\n\n    # Tests that the function returns an empty dictionary when the JSON string is not parseable and cannot be fixed using either technique.\n    # @requires_api_key(\"OPEN_API_KEY\")\n    def test_fix_and_parse_json_can_not(self, mocker):\n        # Edge case test case where the JSON string is not parseable and cannot be fixed using either technique\n        json_string = \"This is not a JSON string\"\n\n        # mock try_ai_fix to avoid calling the AI model:\n        mocker.patch(\"autogpt.json_utils.json_fix_llm.try_ai_fix\", return_value={})\n\n        expected_output = {}\n\n        # Use the actual function name in the test\n        result = fix_json_using_multiple_techniques(json_string)\n\n        assert result == expected_output\n\n    # Tests that the function returns an empty dictionary when the JSON string is empty.\n    # @requires_api_key(\"OPEN_API_KEY\")\n    def test_fix_and_parse_json_empty_string(self, mocker):\n        # Arrange\n        json_string = \"\"\n\n        # Act\n        # mock try_ai_fix to avoid calling the AI model:\n        mocker.patch(\"autogpt.json_utils.json_fix_llm.try_ai_fix\", return_value={})\n\n        result = fix_and_parse_json(json_string)\n\n        # Assert\n        assert result == {}\n\n    # Tests that the function successfully fixes and parses a JSON string that contains escape characters.\n    def test_fix_and_parse_json_escape_characters(self):\n        # Arrange\n        json_string = '{\"text\": \"This is a \\\\\"test\\\\\" string.\"}'\n\n        # Act\n        result = fix_json_using_multiple_techniques(json_string)\n\n        # Assert\n        assert result == {\"text\": 'This is a \"test\" string.'}\n\n    # Tests that the function successfully fixes and parses a JSON string that contains nested objects or arrays.\n    def test_fix_and_parse_json_nested_objects(self):\n        # Arrange\n        json_string = '{\"person\": {\"name\": \"John\", \"age\": 30}, \"hobbies\": [\"reading\", \"swimming\"]}'\n\n        # Act\n        result = fix_json_using_multiple_techniques(json_string)\n\n        # Assert\n        assert result == {\n            \"person\": {\"name\": \"John\", \"age\": 30},\n            \"hobbies\": [\"reading\", \"swimming\"],\n        }\n"
  },
  {
    "path": "tests/unit/test_llm_utils.py",
    "content": "import pytest\nfrom openai.error import APIError, RateLimitError\n\nfrom autogpt.llm import llm_utils\n\n\n@pytest.fixture(params=[RateLimitError, APIError])\ndef error(request):\n    if request.param == APIError:\n        return request.param(\"Error\", http_status=502)\n    else:\n        return request.param(\"Error\")\n\n\ndef error_factory(error_instance, error_count, retry_count, warn_user=True):\n    class RaisesError:\n        def __init__(self):\n            self.count = 0\n\n        @llm_utils.retry_openai_api(\n            num_retries=retry_count, backoff_base=0.001, warn_user=warn_user\n        )\n        def __call__(self):\n            self.count += 1\n            if self.count <= error_count:\n                raise error_instance\n            return self.count\n\n    return RaisesError()\n\n\ndef test_retry_open_api_no_error(capsys):\n    @llm_utils.retry_openai_api()\n    def f():\n        return 1\n\n    result = f()\n    assert result == 1\n\n    output = capsys.readouterr()\n    assert output.out == \"\"\n    assert output.err == \"\"\n\n\n@pytest.mark.parametrize(\n    \"error_count, retry_count, failure\",\n    [(2, 10, False), (2, 2, False), (10, 2, True), (3, 2, True), (1, 0, True)],\n    ids=[\"passing\", \"passing_edge\", \"failing\", \"failing_edge\", \"failing_no_retries\"],\n)\ndef test_retry_open_api_passing(capsys, error, error_count, retry_count, failure):\n    call_count = min(error_count, retry_count) + 1\n\n    raises = error_factory(error, error_count, retry_count)\n    if failure:\n        with pytest.raises(type(error)):\n            raises()\n    else:\n        result = raises()\n        assert result == call_count\n\n    assert raises.count == call_count\n\n    output = capsys.readouterr()\n\n    if error_count and retry_count:\n        if type(error) == RateLimitError:\n            assert \"Reached rate limit, passing...\" in output.out\n            assert \"Please double check\" in output.out\n        if type(error) == APIError:\n            assert \"API Bad gateway\" in output.out\n    else:\n        assert output.out == \"\"\n\n\ndef test_retry_open_api_rate_limit_no_warn(capsys):\n    error_count = 2\n    retry_count = 10\n\n    raises = error_factory(RateLimitError, error_count, retry_count, warn_user=False)\n    result = raises()\n    call_count = min(error_count, retry_count) + 1\n    assert result == call_count\n    assert raises.count == call_count\n\n    output = capsys.readouterr()\n\n    assert \"Reached rate limit, passing...\" in output.out\n    assert \"Please double check\" not in output.out\n\n\ndef test_retry_openapi_other_api_error(capsys):\n    error_count = 2\n    retry_count = 10\n\n    raises = error_factory(APIError(\"Error\", http_status=500), error_count, retry_count)\n\n    with pytest.raises(APIError):\n        raises()\n    call_count = 1\n    assert raises.count == call_count\n\n    output = capsys.readouterr()\n    assert output.out == \"\"\n\n\ndef test_chunked_tokens():\n    text = \"Auto-GPT is an experimental open-source application showcasing the capabilities of the GPT-4 language model\"\n    expected_output = [\n        (\n            13556,\n            12279,\n            2898,\n            374,\n            459,\n            22772,\n            1825,\n            31874,\n            3851,\n            67908,\n            279,\n            17357,\n            315,\n            279,\n            480,\n            2898,\n            12,\n            19,\n            4221,\n            1646,\n        )\n    ]\n    output = list(llm_utils.chunked_tokens(text, \"cl100k_base\", 8191))\n    assert output == expected_output\n"
  },
  {
    "path": "tests/unit/test_plugins.py",
    "content": "import pytest\n\nfrom autogpt.config import Config\nfrom autogpt.plugins import (\n    denylist_allowlist_check,\n    inspect_zip_for_modules,\n    scan_plugins,\n)\n\nPLUGINS_TEST_DIR = \"tests/unit/data/test_plugins\"\nPLUGIN_TEST_ZIP_FILE = \"Auto-GPT-Plugin-Test-master.zip\"\nPLUGIN_TEST_INIT_PY = \"Auto-GPT-Plugin-Test-master/src/auto_gpt_vicuna/__init__.py\"\nPLUGIN_TEST_OPENAI = \"https://weathergpt.vercel.app/\"\n\n\ndef test_inspect_zip_for_modules():\n    result = inspect_zip_for_modules(str(f\"{PLUGINS_TEST_DIR}/{PLUGIN_TEST_ZIP_FILE}\"))\n    assert result == [PLUGIN_TEST_INIT_PY]\n\n\n@pytest.fixture\ndef mock_config_denylist_allowlist_check():\n    class MockConfig:\n        \"\"\"Mock config object for testing the denylist_allowlist_check function\"\"\"\n\n        plugins_denylist = [\"BadPlugin\"]\n        plugins_allowlist = [\"GoodPlugin\"]\n        authorise_key = \"y\"\n        exit_key = \"n\"\n\n    return MockConfig()\n\n\ndef test_denylist_allowlist_check_denylist(\n    mock_config_denylist_allowlist_check, monkeypatch\n):\n    # Test that the function returns False when the plugin is in the denylist\n    monkeypatch.setattr(\"builtins.input\", lambda _: \"y\")\n    assert not denylist_allowlist_check(\n        \"BadPlugin\", mock_config_denylist_allowlist_check\n    )\n\n\ndef test_denylist_allowlist_check_allowlist(\n    mock_config_denylist_allowlist_check, monkeypatch\n):\n    # Test that the function returns True when the plugin is in the allowlist\n    monkeypatch.setattr(\"builtins.input\", lambda _: \"y\")\n    assert denylist_allowlist_check(\"GoodPlugin\", mock_config_denylist_allowlist_check)\n\n\ndef test_denylist_allowlist_check_user_input_yes(\n    mock_config_denylist_allowlist_check, monkeypatch\n):\n    # Test that the function returns True when the user inputs \"y\"\n    monkeypatch.setattr(\"builtins.input\", lambda _: \"y\")\n    assert denylist_allowlist_check(\n        \"UnknownPlugin\", mock_config_denylist_allowlist_check\n    )\n\n\ndef test_denylist_allowlist_check_user_input_no(\n    mock_config_denylist_allowlist_check, monkeypatch\n):\n    # Test that the function returns False when the user inputs \"n\"\n    monkeypatch.setattr(\"builtins.input\", lambda _: \"n\")\n    assert not denylist_allowlist_check(\n        \"UnknownPlugin\", mock_config_denylist_allowlist_check\n    )\n\n\ndef test_denylist_allowlist_check_user_input_invalid(\n    mock_config_denylist_allowlist_check, monkeypatch\n):\n    # Test that the function returns False when the user inputs an invalid value\n    monkeypatch.setattr(\"builtins.input\", lambda _: \"invalid\")\n    assert not denylist_allowlist_check(\n        \"UnknownPlugin\", mock_config_denylist_allowlist_check\n    )\n\n\n@pytest.fixture\ndef config_with_plugins():\n    \"\"\"Mock config object for testing the scan_plugins function\"\"\"\n    # Test that the function returns the correct number of plugins\n    cfg = Config()\n    cfg.plugins_dir = PLUGINS_TEST_DIR\n    cfg.plugins_openai = [\"https://weathergpt.vercel.app/\"]\n    return cfg\n\n\n@pytest.fixture\ndef mock_config_openai_plugin():\n    \"\"\"Mock config object for testing the scan_plugins function\"\"\"\n\n    class MockConfig:\n        \"\"\"Mock config object for testing the scan_plugins function\"\"\"\n\n        plugins_dir = PLUGINS_TEST_DIR\n        plugins_openai = [PLUGIN_TEST_OPENAI]\n        plugins_denylist = [\"AutoGPTPVicuna\"]\n        plugins_allowlist = [PLUGIN_TEST_OPENAI]\n\n    return MockConfig()\n\n\ndef test_scan_plugins_openai(mock_config_openai_plugin):\n    # Test that the function returns the correct number of plugins\n    result = scan_plugins(mock_config_openai_plugin, debug=True)\n    assert len(result) == 1\n\n\n@pytest.fixture\ndef mock_config_generic_plugin():\n    \"\"\"Mock config object for testing the scan_plugins function\"\"\"\n\n    # Test that the function returns the correct number of plugins\n    class MockConfig:\n        plugins_dir = PLUGINS_TEST_DIR\n        plugins_openai = []\n        plugins_denylist = []\n        plugins_allowlist = [\"AutoGPTPVicuna\"]\n\n    return MockConfig()\n\n\ndef test_scan_plugins_generic(mock_config_generic_plugin):\n    # Test that the function returns the correct number of plugins\n    result = scan_plugins(mock_config_generic_plugin, debug=True)\n    assert len(result) == 1\n"
  },
  {
    "path": "tests/unit/test_spinner.py",
    "content": "# Generated by CodiumAI\nimport time\n\nfrom autogpt.spinner import Spinner\n\n\"\"\"\nCode Analysis\n\nMain functionalities:\nThe Spinner class provides a simple way to display a spinning animation while a process is running. It can be used to indicate that a process is ongoing and to provide visual feedback to the user. The class can be used as a context manager, which means that it can be used with the 'with' statement to automatically start and stop the spinner animation.\n\nMethods:\n- __init__(self, message: str = \"Loading...\", delay: float = 0.1) -> None: Initializes the Spinner class with a message to display and a delay between each spinner update.\n- spin(self) -> None: Spins the spinner animation while the process is running.\n- __enter__(self): Starts the spinner animation when used as a context manager.\n- __exit__(self, exc_type, exc_value, exc_traceback) -> None: Stops the spinner animation when used as a context manager.\n- update_message(self, new_message, delay=0.1): Updates the message displayed by the spinner animation.\n\nFields:\n- spinner: An itertools.cycle object that contains the characters used for the spinner animation.\n- delay: The delay between each spinner update.\n- message: The message to display.\n- running: A boolean value that indicates whether the spinner animation is running.\n- spinner_thread: A threading.Thread object that runs the spin method in a separate thread.\n\"\"\"\n\nALMOST_DONE_MESSAGE = \"Almost done...\"\nPLEASE_WAIT = \"Please wait...\"\n\n\ndef test_spinner_initializes_with_default_values():\n    \"\"\"Tests that the spinner initializes with default values.\"\"\"\n    with Spinner() as spinner:\n        assert spinner.message == \"Loading...\"\n        assert spinner.delay == 0.1\n\n\ndef test_spinner_initializes_with_custom_values():\n    \"\"\"Tests that the spinner initializes with custom message and delay values.\"\"\"\n    with Spinner(message=PLEASE_WAIT, delay=0.2) as spinner:\n        assert spinner.message == PLEASE_WAIT\n        assert spinner.delay == 0.2\n\n\n#\ndef test_spinner_stops_spinning():\n    \"\"\"Tests that the spinner starts spinning and stops spinning without errors.\"\"\"\n    with Spinner() as spinner:\n        time.sleep(1)\n        spinner.update_message(ALMOST_DONE_MESSAGE)\n        time.sleep(1)\n    assert spinner.running == False\n\n\ndef test_spinner_updates_message_and_still_spins():\n    \"\"\"Tests that the spinner message can be updated while the spinner is running and the spinner continues spinning.\"\"\"\n    with Spinner() as spinner:\n        assert spinner.running == True\n        time.sleep(1)\n        spinner.update_message(ALMOST_DONE_MESSAGE)\n        time.sleep(1)\n        assert spinner.message == ALMOST_DONE_MESSAGE\n    assert spinner.running == False\n\n\ndef test_spinner_can_be_used_as_context_manager():\n    \"\"\"Tests that the spinner can be used as a context manager.\"\"\"\n    with Spinner() as spinner:\n        assert spinner.running == True\n    assert spinner.running == False\n"
  },
  {
    "path": "tests/unit/test_url_validation.py",
    "content": "import pytest\nfrom pytest import raises\n\nfrom autogpt.url_utils.validators import validate_url\n\n\n@validate_url\ndef dummy_method(url):\n    return url\n\n\nsuccessful_test_data = (\n    (\"https://google.com/search?query=abc\"),\n    (\"https://google.com/search?query=abc&p=123\"),\n    (\"http://google.com/\"),\n    (\"http://a.lot.of.domain.net/param1/param2\"),\n)\n\n\n@pytest.mark.parametrize(\"url\", successful_test_data)\ndef test_url_validation_succeeds(url):\n    assert dummy_method(url) == url\n\n\nbad_protocol_data = (\n    (\"htt://example.com\"),\n    (\"httppp://example.com\"),\n    (\" https://example.com\"),\n)\n\n\n@pytest.mark.parametrize(\"url\", bad_protocol_data)\ndef test_url_validation_fails_bad_protocol(url):\n    with raises(ValueError, match=\"Invalid URL format\"):\n        dummy_method(url)\n\n\nmissing_loc = ((\"http://?query=q\"),)\n\n\n@pytest.mark.parametrize(\"url\", missing_loc)\ndef test_url_validation_fails_bad_protocol(url):\n    with raises(ValueError, match=\"Missing Scheme or Network location\"):\n        dummy_method(url)\n\n\nlocal_file = (\n    (\"http://localhost\"),\n    (\"https://localhost/\"),\n    (\"http://2130706433\"),\n    (\"https://2130706433\"),\n    (\"http://127.0.0.1/\"),\n)\n\n\n@pytest.mark.parametrize(\"url\", local_file)\ndef test_url_validation_fails_local_path(url):\n    with raises(ValueError, match=\"Access to local files is restricted\"):\n        dummy_method(url)\n"
  },
  {
    "path": "tests/unit/test_web_selenium.py",
    "content": "from autogpt.commands.web_selenium import browse_website\n\n\ndef test_browse_website():\n    url = \"https://barrel-roll.com\"\n    question = \"How to execute a barrel roll\"\n\n    response = browse_website(url, question)\n    assert \"Error\" in response\n    # Sanity check that the response is not too long\n    assert len(response) < 200\n"
  },
  {
    "path": "tests/utils.py",
    "content": "import functools\nimport os\nfrom contextlib import contextmanager\n\nimport pytest\n\nfrom autogpt.config import Config\n\n\n@contextmanager\ndef dummy_openai_api_key():\n    # even when we record the VCR cassettes, openAI wants an API key\n    config = Config()\n    original_api_key = config.openai_api_key\n    config.set_openai_api_key(\"sk-dummy\")\n\n    try:\n        yield\n    finally:\n        config.set_openai_api_key(original_api_key)\n\n\ndef requires_api_key(env_var):\n    def decorator(func):\n        @functools.wraps(func)\n        def wrapper(*args, **kwargs):\n            if not os.environ.get(env_var) and env_var == \"OPENAI_API_KEY\":\n                with dummy_openai_api_key():\n                    return func(*args, **kwargs)\n            else:\n                return func(*args, **kwargs)\n\n        return wrapper\n\n    return decorator\n\n\ndef skip_in_ci(test_function):\n    return pytest.mark.skipif(\n        os.environ.get(\"CI\") == \"true\",\n        reason=\"This test doesn't work on GitHub Actions.\",\n    )(test_function)\n\n\ndef get_workspace_file_path(workspace, file_name):\n    return str(workspace.get_path(file_name))\n"
  },
  {
    "path": "tests/vcr/__init__.py",
    "content": ""
  },
  {
    "path": "tests/vcr/openai_filter.py",
    "content": "import json\nimport re\n\n\ndef replace_timestamp_in_request(request):\n    # Check if the request body contains a JSON object\n\n    try:\n        if not request or not request.body:\n            return request\n        body = json.loads(request.body)\n    except ValueError:\n        return request\n\n    if \"messages\" not in body:\n        return request\n\n    for message in body[\"messages\"]:\n        if \"content\" in message and \"role\" in message and message[\"role\"] == \"system\":\n            timestamp_regex = re.compile(r\"\\w{3} \\w{3} \\d{2} \\d{2}:\\d{2}:\\d{2} \\d{4}\")\n            message[\"content\"] = timestamp_regex.sub(\n                \"Tue Jan 01 00:00:00 2000\", message[\"content\"]\n            )\n\n    request.body = json.dumps(body)\n    return request\n\n\ndef before_record_response(response):\n    if \"Transfer-Encoding\" in response[\"headers\"]:\n        del response[\"headers\"][\"Transfer-Encoding\"]\n    return response\n\n\ndef before_record_request(request):\n    filtered_request = filter_hostnames(request)\n    filtered_request_without_dynamic_data = replace_timestamp_in_request(\n        filtered_request\n    )\n    return filtered_request_without_dynamic_data\n\n\ndef filter_hostnames(request):\n    allowed_hostnames = [\n        \"api.openai.com\",\n        \"localhost:50337\",\n    ]  # List of hostnames you want to allow\n\n    if any(hostname in request.url for hostname in allowed_hostnames):\n        return request\n    else:\n        return None\n"
  },
  {
    "path": "tests/vcr/vcr_filter.py",
    "content": "import json\nimport re\nfrom typing import Any, Dict, List\n\nREPLACEMENTS: List[Dict[str, str]] = [\n    {\n        \"regex\": r\"\\w{3} \\w{3} {1,2}\\d{1,2} \\d{2}:\\d{2}:\\d{2} \\d{4}\",\n        \"replacement\": \"Tue Jan  1 00:00:00 2000\",\n    },\n    {\n        \"regex\": r\"<selenium.webdriver.chrome.webdriver.WebDriver[^>]*>\",\n        \"replacement\": \"\",\n    },\n]\n\n\ndef replace_message_content(content: str, replacements: List[Dict[str, str]]) -> str:\n    for replacement in replacements:\n        pattern = re.compile(replacement[\"regex\"])\n        content = pattern.sub(replacement[\"replacement\"], content)\n\n    return content\n\n\ndef replace_timestamp_in_request(request: Any) -> Any:\n    try:\n        if not request or not request.body:\n            return request\n        body = json.loads(request.body)\n    except ValueError:\n        return request\n\n    if \"messages\" not in body:\n        return request\n    body[\n        \"max_tokens\"\n    ] = 0  # this field is incosistent between requests and not used at the moment.\n    for message in body[\"messages\"]:\n        if \"content\" in message and \"role\" in message:\n            if message[\"role\"] == \"system\":\n                message[\"content\"] = replace_message_content(\n                    message[\"content\"], REPLACEMENTS\n                )\n\n    request.body = json.dumps(body)\n    return request\n\n\ndef before_record_response(response: Dict[str, Any]) -> Dict[str, Any]:\n    if \"Transfer-Encoding\" in response[\"headers\"]:\n        del response[\"headers\"][\"Transfer-Encoding\"]\n    return response\n\n\ndef before_record_request(request: Any) -> Any:\n    filtered_request = filter_hostnames(request)\n    filtered_request_without_dynamic_data = replace_timestamp_in_request(\n        filtered_request\n    )\n    return filtered_request_without_dynamic_data\n\n\ndef filter_hostnames(request: Any) -> Any:\n    allowed_hostnames: List[str] = [\n        \"api.openai.com\",\n        \"localhost:50337\",\n    ]\n\n    # Add your implementation here for filtering hostnames\n    if any(hostname in request.url for hostname in allowed_hostnames):\n        return request\n    else:\n        return None\n"
  },
  {
    "path": "tests.py",
    "content": "import unittest\n\nimport coverage\n\nif __name__ == \"__main__\":\n    # Start coverage collection\n    cov = coverage.Coverage()\n    cov.start()\n\n    # Load all tests from the 'autogpt/tests' package\n    suite = unittest.defaultTestLoader.discover(\"./tests\")\n\n    # Run the tests\n    unittest.TextTestRunner().run(suite)\n\n    # Stop coverage collection\n    cov.stop()\n    cov.save()\n\n    # Report the coverage\n    cov.report(show_missing=True)\n"
  }
]